String vs StringBuilder vs StringBuffer
공통점은 문자열을 다루는 객체이다
차이점은 간단하게 정리하자면 아래와 같다
String - 불변
StringBuilder - 가변
StringBuffer - 가변 + 스레드 안전(동기화 지원)
특성 | String | StringBuilder | StringBuffer |
변경 가능성 | 불변 (Immutable) | 가변 (Mutable) | 가변 (Mutable) |
스레드 안전성 | X | X | O (동기화 지원) |
1. String 객체부터 살펴보자
java.lang.String을 살펴보면, final이 붙어있어서 값을 바꿀 수 없음을 알 수 있다.
하지만 아래 예제를 보면 값이 변할 수 있다?
String data = "합쳐";
data = data + "지는데오?";
System.out.println(data);
스포하자면 사실은 값이 변하는게 아니다.
메모리에서는 합쳐지는데오 라는 영역을 새로 만들고 -> data는 그것을 참조하는 형태가 된다.
이전에 있던 합쳐라는 값은 어떻게 되느냐?
garbage 값이 됩니다. 이런것들이 쌓이면 성능상 문제가 생길 수 있죠.
2. StringBuilder 객체
java.lang.StringBuilder에는 final이 붙어있지 않음을 볼 수 있다.
String객체와 다르게 가변적으로 문자열 크기를 변경 할 수 있다 -> append를 주로 사용하여, 문자열을 붙여준다
아래 예제와 그림을 보자
StringBuilder data = new StringBuilder(); // 생성자에 값을 안넣어주면, 기본 16바이트
data.append("합쳐");
data.append("지는데오?");
System.out.println(data);
이 결과를 그려보면 아래와 같다.
String과 다르게 쓰레기값이 생기지 않습니다.
결론은 문자열이 자주 추가, 수정, 삭제가 일어난다면 StringBuilder가 비용이 좋다라고 할 수 있습니다.
3. StringBuffer 객체
StringBuilder와 동일하게 AbstractStringBuilder를 상속 받고 있으므로, 비슷하다고 볼 수 있습니다.
하지만! 아래쪽을 내려보면 StringBuffer는 차이점이 있습니다.
StringBuffer는 synchronized라는 스레드 동기화 관련 키워드가 들어가있습니다.
사용법은 StringBuilder와 동일하니까
StringBuilder vs StringBuffer의 차이를 한 눈에 볼 수 있는 예제를 작성해보는게 좋을 것 같네요
StringBuilder strBuilder = new StringBuilder();
StringBuffer strBuffer = new StringBuffer();
Thread threadBuilder = new Thread(() -> {
for(int i=1; i<=5000; i++) {
strBuilder.append("짱");
strBuffer.append("짱");
}
});
Thread threadBuffer = new Thread(() -> {
for(int i=1; i<=5000; i++) {
strBuilder.append("짱");
strBuffer.append("짱");
}
});
threadBuilder.start();
threadBuffer.start();
try {
threadBuilder.join();
threadBuffer.join();
} catch (Exception e) {}
System.out.println("StringBuilder의 length : " + strBuilder.length());
System.out.println("StringBuffer의 length : " + strBuffer.length());
스레드 두개를 돌려서 짱이라는 한 글자를 5000번씩 넣어주면 결과는 10000씩 나오지 않을까 싶지만,
StringBuilder는 동기화를 지원하지 않아서 9930이 나옴을 볼 수 있다.
4. 정리
자주 변경되는 문자열 데이터라는 기준하에 성능은 아래와 같다.
String < StringBuffer <StringBuilder
스레드 세이프 환경이라면 StringBuilder가 이상적이라고 볼 수있다.
참고자료
this is java 책 - 신용권
'자바' 카테고리의 다른 글
[자바] Form 데이터 파싱후 JUnit5로 테스트 (x-www-form-urlencoded) (2) | 2024.02.17 |
---|---|
[자바]Java Reflection: ModelMapper를 활용한 효율적인 객체 매핑 기법 (1) | 2024.02.11 |
[자바] 레코드(Records) : 코드 간결성과 효율성을 높이는 새로운 방법 (0) | 2024.01.28 |
[자바] Try-with-resources in Java: 코드를 깔끔하게 유지하는 현대적 방법 (0) | 2024.01.21 |
[자바] 클래스 파일 구조, VM명세서 (0) | 2023.11.14 |