자바에서 문자열을 다루는 대표적인 클래스로 String, StringBuffer, StringBuilder 가 있습니다.
연산 횟수가 많아지거나 멀티스레드, Race condition 등의 상황이 자주 발생한다면 각 클래스의 특징을 이해하고 상황에 맞는 적절한 클래스를 사용해주어야 합니다.
String과 StringBuffer/StringBuilder 클래스의 가장 큰 차이점은 String은 불변(immutable)의 속성을 갖는다는 점입니다.
String str = "hello"; // String str = new String("hello");
str = str + " world"; // [ hello world ]
위 예제에서 "hello" 값을 가지고 있던 String 클래스의 참조변수 str이 가리키는 곳에 저장된 "hello"에 "world" 문자열을 더해 "hello world"로 변경된 것으로 착각할 수 있는데 아닙니다.
기존에 "hello" 값이 들어가 있던 String 클래스의 참조변수 str이 "hello world"라는 값을 가지고 있는 새로운 메모리영역을 가리키도록 변경되고 처음 선언했던 "hello"로 값이 할당되어 있던 메모리 영역은 garbage로 남아있다가 GC에 의해 사라지게 됩니다.
String 클래스는 불변하기 때문에 문자열을 수정하는 시점에 새로운 String 인스턴스가 생성된 것입니다.
그러나 문자열 추가, 수정, 삭제 등의 연산이 빈번하게 발생하는 알고리즘에 String 클래스를 사용하면 힙 메모리(Heap)에 많은 임시 Garbage가 생성되어 힙메모리 부족으로 어플리케이션 성능에 치명적인 영향을 끼치게 됩니다.
이를 해결하기 위해 Java에서는 가변성(mutable)을 가지는 StringBuffer/StringBuilder 클래스를 도입했습니다.
String 과는 반대로 StringBuffer/StringBuilder는 가변성을 가지기 때문에 .append()
.delete()
등의 메소드를 이용하여 동일 객체 내에서 문자열을 변경하는 것이 가능합니다.
StringBuffer sb= new StringBuffer("hello");
sb.append(" world");
String vs StringBuffer 성능 참고
https://velog.io/@rlooo/println%EA%B3%BC-StringBuilder-%EC%86%8D%EB%8F%84-%EC%B0%A8%EC%9D%B4
StringBuffer와 StringBuilder의 가장 큰 차이점은 동기화의 유무입니다.