StringBuffer 클래스
1. StringBuffer 클래스
String 클래스는 인스턴스를 생성할 때 지정된 문자열을 변경할 수 없지만 StringBuffer 클래스는 변경이 가능하다.
내부적으로 문자열 편집을 위한 버퍼(buffer)를 가지고 있으며, StringBuffer인스턴스를 생성할 때,
그 크기를 지정할 수 있다. 이 때, 편집할 문자열의 길이를 고려하여 버퍼의 길이를 충분히 잡아주는 것이 좋다.
편집 중인 문자열이 버퍼의 길이를 넘어서게 되면 버퍼의 길이를 늘려주는 작업이 추가로 수행되어야 하기 때문이다.
StringBuffer클래스는 String클래스와 유사한 점이 많다. 아래의 코드에서 알 수 있듯이, StringBuffer 클래스는
String클래스와 같이 문자열을 저장하기 위한 char형 배열의 참조변수를 인스턴스변수로 선언해 놓고 있다.
StringBuffer 인스턴스가 생성될 때, char형이 배열이 생성되며 이 때 생성된 char형 배열을
인스턴스변수 value가 참조하게 된다.
public final class StringBuffer implements java.io.Serializable {
private char [] value;
...
}
2. StringBuffer 의 생성자
StringBuffer클래스의 인스턴스를 생성할 때, 적절한 길이의 char형 배열이 생성되고 , 이 배열은 문자열을 저장하고 편집하기 위한
공간(buffer)로 사용된다.
StringBuffer 인스턴스를 생성할 때는 생성자 StringBuffer(int length) 를 사용해서 StringBuffer인스턴스에 저장될 문자열의 길이를 고려하여
지정해주는 것이 좋다. StringBuffer 인스턴스를 생성할 때, 크기를 지정해주지 않으면 16개의 문자를 저장할 수 잇는 크기의 버퍼를
생성한다.
public StringBuffer(int length){
value = new char[length] ;
shared = false ;
}
public StringBuffer(int length){
this(16)
}
버퍼의 크기를 지정하지 않으면 버퍼의 크기는 자동으로 16이 된다.
public StringBuffer(String str){
this(strVal.length() + 16);
append(str)
}
지정한 문자열의 길이보다 16이 더 크게 버퍼를 생성한다.
3. StringBuffer의 변경
String과 달리 StringBuffer는 내용을 변경할 수 있다. 예를 들어 아래와 같이 StringBuffer를 생성하였다고 가정하자.
StringBuffer sb = new StringBuffer("abc")
sb.append("123") ; // sb의 내용 뒤에 "123"을 추가한다.
append()는 반환타입이 자기 자신의 주소를 반환한다. 그래서 아래와 같은 문장이 수행되면 , sb에 새로운 문자열이 추가되고
sb자신의 주소를 반환하여 sb2에는 sb의 주소인 0 x 100이 저장된다.
StringBuffer sb2 = sb.append("ZZ"); // sb의 내용 뒤에 "ZZ" 추가
System.out.println(sb); // abc123zz
System.out.println(sb2); // abc123zz
sb와 sb2가 모두 같은 StringBuffer 인스턴스를 가르키고 있으므로 같은 내용이 출력된다. 그래서 하나의 StringBuffer인스턴스에
대해 아래와 같이 연속적으로 아래와 같이 연속적으로 append()를 호출하는 것이 가능하다.
StringBuffer sb = new StringBuffer("abc");
sb.append("123").append("ZZ");
출력 결과 : "abc123ZZ"
만일 append()의 반환타입이 void라면 이렇게 할 수 없었을 것이다.
3. StringBuffer 의 비교
String인스턴스간의 비교에 대해서 학습하면서 '=='와 equals 메서드의 차이점을 알아봤다.
String 클래스에서는 equals 메서드를 오버라이딩해서 문자열의 내용을 비교하도록 구현되어 있지만, StringBuffe 클래스는
equals 메서드를 오버라이딩 하지 않기 때문에 StringBuffer클래스의 equals 메서드를 사용해도 등가비교연산자(==)로
비교한 것과 같은 결과를 얻는다.
그렇기 때문에 StringBuff인스턴스에서 toString()을 호출하여 문자열로 반환한 후 여기에 equals메서드를 사용해서
비교해야 한다. 다음 예제를 참고하자.
3. StringBuilder
StringBuffer는 멀티쓰레드에 안전하도록 동기화되어있다. 아직은 배우지 않았지만 동기화가 StringBuffer의 성능을 떨어뜨려
멀티쓰레드로 작성된 프로그램이 아닌 경우 , StringBuffer의 동기화는 불필요하게 성능만 떨어뜨린다.
그래서 StringBuffer에서 쓰레드의 동기화만 뺀 StringBuilder가 새로 추가되었다.
StringBuilder는 StringBuffer와 완전히 똑같은 기능으로 작성되어 있어서, 소스코드에서 StringBuffer 대신 StringBuilder를
사용하도록 바꾸기만 하면 된다. 즉 , StringBuffer 타입의 참조변수를 선언한 부분과 StringBuffer의 생성자만 바꾸면 된다는 말이다.
StringBuffer sb;
sb = new StringBuffer();
sb.append("abc");
// Builder로 수정된 코드
StringBuilder sb;
sb = new StringBuilder();
sb.append("abc");
StringBuffer도 충분히 성능이 좋기 때문에 성능 향상이 반드시 필요한 경우를 제외하고는 기존에 작성한 코드에서 StringBuffer를
StringBuilder로 굳이 바꿀 필요는 없다.