자바에서는 문자열을 다루는 클래스로 String, StringBuffer, StringBuilder이라는 3가지 클래스가 있습니다. 위 3가지 클래스는 모두 문자열을 저장하고 관리하는 클래스이며 각 클래스 간에는 조금의 차이가 있습니다.
String과 StringBuffer, StringBuilder의 차이점
String 객체는 한번 생성되면 할당된 공간이 변하지 않지만 StringBuffer나 StringBuilder의 경우 객체의 공간이 부족해지는 경우 버퍼의 크기를 유연하게 늘려줍니다. 이러한 특징을 일컬어 String은 불변(immutable)하고 StringBuffer와 StringBuilder는 가변(mutable)하다라고 합니다.
StringBuffer와 StringBuilder의 차이점
StringBuffer와 StringBuilder클래스는 둘 다 크기가 유연하게 변하는 가변적인 특성을 가지고 있으며 제공하는 메서드도 같고 사용하는 방법도 동일합니다. 하지만 두 클래스는 동기화 지원의 유무가 다릅니다. StringBuffer는 각 메소드 별로 synchronized keyword가 존재하여 멀티 스레드 상태에서 동기화를 지원하고 StringBuilder는 단일 스레드 환경에서만 사용하도록 설계되어 있습니다. StringBuilder가 StringBuffer보다 속도는 더 빠르지만 현업에서는 언제 멀티스레드 환경에서 돌아가지 알지 못하기에 안정적인 StringBuffer로 통일하여 코딩하는것이 좋습니다.
StringBuffer와 StringBuilder클래스를 사용하면 좋은 경우
String은 내부의 문자열을 수정할 수 없습니다. 크기가 고정되어 있기 때문입니다. 그렇기에 문자열을 수정할 때마다 새로운 문자열을 리턴합니다. 가장 대표적인 예가 String객체를 + 연산할 경우입니다.
String s = "ABC";
s += "DEF";
ABC에 DEF가 더하면 s에 "ABC"에서 "DEF"가 추가되어 s의 값이 ABCDEF가 된다고 생각할 수 있지만 String객체는 내부 데이터를 수정할 수 없으므로 "ABC"에 "DEF"가 추가된 "ABCDEF"라는 새로운 String객체가 생성되고 data변수는 새로 생성된 String객체를 참조하게 됩니다. 그리고 기존에 있던 String객체는 참조되지 않게 되어 가비지 컬렉션의 메모리 해제를 기다리게 됩니다. 이렇듯 문자열을 합쳐주는 + 연산자를 많이 사용하면 할수록 String 객체의 수가 늘어나기 때문에 프로그램 성능이 느려집니다. 아래는 그림으로 위 내용을 표현한 것입니다.
그래서 문자열을 변경하는 작업이 많을 경우에는 String을 사용하는 것보다 StringBuffer나 StringBuilder를 사용하는 것이 좋습니다. 두 클래스는 내부 Buffer에 문자열을 저장해두고 그 안에서 추가, 수정, 삭제 작업을 할 수 있도록 설계되어 있습니다. 그렇기에 String처럼 새로운 객체를 만들지 않고도 문자열을 수정할 수 있습니다.
※ Buffer : 데이터를 임시로 저장하는 메모리
String을 사용하면 좋은 경우
StringBuffer나 StringBuilder을 생성할 경우 buffer의 크기를 초기에 설정해줘야하는데 이러한 동작으로 인해 String객체보다 생성 속도가 많이 느리게 됩니다. 그리고 StringBuffer나 StringBuilder에서 문자열 수정을 할 경우에도 마찬가지로 버퍼의 크기를 늘리고 줄이고 명칭을 변경해야하는 내부적인 연산이 필요하므로 많은 양의 문자열 수정이 아니라면 String객체를 사용하는것이 오히려 나을 수 있습니다. 또한 String 클래스는 크기가 고정되어 있으므로 단순하게 읽는 조회 연산에서는 StringBuffer나 StringBuilder클래스보다 빠르게 읽을 수 있는 장점이 있습니다. 결론적으로 말하면 문자열 연산이 많을 경우에는 String클래스를 사용하면 되고 연산이 많다면 StringBuffer나 StringBuilder를 사용하면됩니다.
StringBuffer 간단 예제
public class StringBuffer_Ex {
public static void main(String[] args) {
String s = "abcdefg";
StringBuffer sb = new StringBuffer(s); // String -> StringBuffer
System.out.println("처음 상태 : " + sb); //처음상태 : abcdefg
System.out.println("문자열 String 변환 : " + sb.toString()); //String 변환하기
System.out.println("문자열 추출 : " + sb.substring(2,4)); //문자열 추출하기
System.out.println("문자열 추가 : " + sb.insert(2,"추가")); //문자열 추가하기
System.out.println("문자열 삭제 : " + sb.delete(2,4)); //문자열 삭제하기
System.out.println("문자열 연결 : " + sb.append("hijk")); //문자열 붙이기
System.out.println("문자열의 길이 : " + sb.length()); //문자열의 길이구하기
System.out.println("용량의 크기 : " + sb.capacity()); //용량의 크기 구하기
System.out.println("문자열 역순 변경 : " + sb.reverse()); //문자열 뒤집기
System.out.println("마지막 상태 : " + sb); //마지막상태 : kjihgfedcba
}
}
StringBuilder 간단 예제
public class StringBuilder_Ex {
public static void main(String[] args) {
String s = "abcdefg";
StringBuilder sb = new StringBuilder(s); // String -> StringBuilder
System.out.println("처음 상태 : " + sb); //처음상태 : abcdefg
System.out.println("문자열 String 변환 : " + sb.toString()); //String 변환하기
System.out.println("문자열 추출 : " + sb.substring(2,4)); //문자열 추출하기
System.out.println("문자열 추가 : " + sb.insert(2,"추가")); //문자열 추가하기
System.out.println("문자열 삭제 : " + sb.delete(2,4)); //문자열 삭제하기
System.out.println("문자열 연결 : " + sb.append("hijk")); //문자열 붙이기
System.out.println("문자열의 길이 : " + sb.length()); //문자열의 길이구하기
System.out.println("용량의 크기 : " + sb.capacity()); //용량의 크기 구하기
System.out.println("문자열 역순 변경 : " + sb.reverse()); //문자열 뒤집기
System.out.println("마지막 상태 : " + sb); //마지막상태 : kjihgfedcba
}
}
'Language > Java' 카테고리의 다른 글
[Java] 자바 배열을 복사하는 다양한 방법 (깊은복사, 얕은복사) (7) | 2020.05.18 |
---|---|
[Java] 래퍼 클래스(Wrapper Class)란 무엇인가? (박싱, 언박싱) (11) | 2020.05.16 |
[Java] 문자열 비교하기 == , equals() 의 차이점 (12) | 2020.05.04 |
[Java] 문자열 길이 구하기, 제한하기 length() (3) | 2020.05.03 |