레넌의 개발 일기

String, StringBuilder, StringBuffer 본문

자바

String, StringBuilder, StringBuffer

brorae 2022. 2. 28. 15:36

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를 사용하자.