String / StringBuffer / StringBuilder
Java를 사용하며 접하게 되는 문자열 클래스들이다.
모두 문자열을 저장하고 관리하는 클래스들로 각 클래스 간에는 조금의 차이가 있다.
String VS StringBuffer / StringBuilder
String 객체는 한번 생성되면 할당된 공간이 변하지 않지만 StringBuffer나 StringBuilder의 경우 객체의 공간이 부족해지는 경우 버퍼의 크기를 유연하게 늘려준다. 이러한 특징을 일컬어 String은 불변(immutable)하고 StringBuffer와 StringBuilder는 가변(mutable)하다라고 한다.
StringBuffer VS StringBuilder
StringBuffer / StringBuilder클래스는 둘 다 크기가 유연하게 변하는 가변적인 특성을 가지고 있으며 제공하는 메서드도 같고 사용하는 방법도 동일하다. 하지만 두 클래스는 동기화 지원의 유무가 다르다.
StringBuffer는 각 메서드 별로 synchronized keyword가 존재하여 멀티 스레드 상태에서 동기화를 지원하고 StringBuilder는 단일 스레드 환경에서만 사용하도록 설계되어 있다. StringBuilder가 StringBuffer보다 속도는 더 빠르지만 현업에서는 언제 멀티스레드 환경에서 돌아갈지 모르기 때문에 안정적인 StringBuffer로 통일하여 코딩하는 것이 좋다고 한다.
언제 StringBuffer & StringBuilder 클래스를 사용해야 하는가
String은 내부의 문자열을 수정할 수 없다. 크기가 고정되어 있기 때문이다. 그렇기에 문자열을 수정할 때 마다 새로운 문자열을 리턴한다. 가장 대표적인 예가 바로 String 객체를 + 연산할 경우이다.
String str = "Taking an extra";
str += "step";
"Taking an extra"에 "step"을 더하면 str에 "Taking an extra"에서 "step"이 추가되어 str의 값이 "Taking an extra step"이 된다고 생각할 수 있지만 String객체는 내부 데이터를 수정할 수 없으므로 "Taking an extra"에 "extra"가 추가된 "Taking an extra step"이라는 새로운 String객체가 생성되고 data변수는 새로 생성된 String객체를 참조하게 된다. 그리고 기존에 있던 String객체는 참조되지 않게 되어 Garbage Collection의 메모리 해제를 기다리게 된다. 이렇듯 문자열을 합쳐주는 + 연산자를 많이 사용하면 할수록 String 객체의 수가 늘어나기 때문에 프로그램 성능이 느려진다.
그래서 문자열을 변경하는 작업이 많을 경우 Stirng 보다 StringBuffer나 StringBuilder를 사용하는 것이 좋다. 두 클래스는 내부 Buffer에 문자열을 저장해두고 그 안에서 추가, 수정, 삭제 작업을 할 수 있도록 설계되어 있다. 그렇기 때문에 String처럼 새로운 객체를 만들지 않고도 문자열을 수정할 수 있다.
언제 String 클래스를 사용해야 하는가
StringBuffer & StringBuilder를 생성할 경우에 buffer의 크기를 초기에 설정해줘야 하는데 이러한 동작으로 인해 String객체보다 생성 속도가 많이 느리게 된다. 그리고 StringBuffer & StringBuilder에서 문자열 수정을 할 경우 마찬가지로 buffer의 크기를 늘리고 줄이고 명칭을 변경해야 하는 내부적인 연산이 필요하므로 많은 양의 문자열 수정이 아니라면 String객체를 사용하는 것이 오히려 효율적일 수 있다. 또한 String클래스는 크기가 고정되어 있으므로 단순하게 읽는 조회 연산에서는 StringBuffer & StringBuilder 클래스보다 빠르게 읽을 수 있다는 장점이 있다.
결론적으로 짧은 문자열을 더하고 문자열 연산이 적을 경우에는 String 클래스를 사용하면 된다.
'JAVA' 카테고리의 다른 글
[Java] 📚 배열 정렬하기 Arrays.sort() (0) | 2022.08.17 |
---|---|
[Java] 📚 BufferedReader / BufferedWriter를 활용한 빠른 입출력 (3) | 2022.05.28 |
[JAVA] Exception in thread "main" java.lang.StringIndexOutOfBoundsException (6) | 2022.03.12 |
[JAVA] Exception in thread "main" java.lang.ArithmeticException: / by zero (2) | 2022.03.09 |
JAVA - 반복문 (for문) (0) | 2022.02.05 |