레넌의 개발 일기
String, StringBuilder, StringBuffer 본문
String
문자열을 저장하는 String의 내부의 문자열을 수정할 수 없다. String의 replace() 메소드와 '+' 연산은 내부의 문자를 대치하는 것이 아니라, 대치된 새로운 String객체가 생성되어 리턴한다.
String data = "ABC";
data += "DEF";
위의 코드에서는 "ABC"의 객체와 합쳐진 "ABCDEF"의 객체 총 2개의 객체가 생긴다.
문자열을 결합하는 '+' 연산자를 많이 사용한다면, String 객체의 수가 늘어나기 때문에, 성능이 느려질 수 있다.
String text = "";
for (int i=0;i<1000;i++) {
text += i;
}
System.out.println(text);
JAVA8 버전에서는 위의 코드를 컴파일 하면 JVM에서 아래와 같이 StringBuilder라는 것으로 최적화해서 처리를 해준다.
String text = "";
for (int i=0;i<1000;i++) {
text = new StringBuilder(text).append(i).toString();
}
System.out.println(text)
하지만, 이 코드에서도 매번 StringBuilder를 생성하기 때문에, 비효율적이라고 할 수 있다.
따라서,JAVA11 버전에서는 StringConcatFactory의 makeConcatWithConstants()로 최적화를 해준다.
간단하게 말하면, 이 메소드에서는 String을 매번 만드는 것 대신에 char 배열을 이용해서 처리를 해주고, 마지막에만 String을 만들어주는 방식이다. (final 키워드를 사용하면, 이와 같은 최적화 과정을 생략할 수 있는데, 이는 성능에 이득을 가져다 줄 수 있다.)
StringBuilder vs StringBuffer
StringBuilder는 단일 스레드 환경에서만 사용할 수 있도록 설계되었지만, StringBuffer는 멀티 스레드 환경에서 사용할 수 있도록 동기화가 적용되어 있어 스레드에 안전하다.
하지만, 멀티 스레드 환경에서 문자를 더할 일이 있는지 고민해봐야한다. (StringBuffer는 거의 쓸일 없음)
StringBuilder와 StringBuffer의 사용방법은 동일하다.
StringBuilder sb = new StringBuilder();
StringBuilder sb = new StringBuilder(16);
StringBuilder sb = new StringBuilder("JAVA");
메소드 | 설명 |
append(...) | 문자열 끝에 주어진 매개 값을 추가 |
insert(int offset, ...) | 문자열 중간에 주어진 매개값을 추가 |
delete(int start, int end) | 문자열의 일부분을 삭제 |
deleteCharAt(int index) | 문자열에서 주어진 index의 문자를 삭제 |
replace(int start, int end, String str) | 문자열의 일부분을 다른 문자열로 대치 |
reverse() | 문자열의 순서를 뒤바꿈 |
setCharAt(int index, char ch) | 문자열에서 주어진 index의 문자를 다른 문자로 대치 |
결론
String의 '+' 연산은 JVM에서 자동으로 최적화를 해주기는 하지만, 개발자가 최적화를 해줄 수 있는 부분은 해주는 것이 좋으므로 StringBuilder를 사용하자.
'자바' 카테고리의 다른 글
생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2022.03.20 |
---|---|
Arrays.asList() 와 List.of() 의 차이 (0) | 2022.03.07 |
모든 원시 값과 문자열을 포장하라 (0) | 2022.03.03 |
MVC 패턴이란? (0) | 2022.02.18 |