[Java] - StringBuffer / StringBuilder

janjanee·2021년 6월 15일
1

Java

목록 보기
10/19
post-thumbnail

String vs StringBuffer/StringBuilder

  • String 클래스는 immutable(불변) 하다. 즉 지정된 문자열을 변경할 수 없다.
  • StringBuffer/StringBuilder 클래스는 mutable(가변) 하다.

String은 불변성을 가졌기 때문에 동일한 문자열을 자주 읽어들이는 경우 String을 사용하면 좋다.
그러나 문자열 연산(추가, 수정, 사게)이 자주 일어난다면 계속 새로운 String 인스턴스가 생성되는 문제가 있다.

반면 StringBuffer/StringBuilder는 가변성을 갖기 때문에, 동일한 객체내에서 문자열 변경이 가능하다.
따라서 문자열 연산(추가, 수정, 사게)이 빈번하다면 StringBuffer/StringBuilder를 사용하면 된다.


StringBuffer 생성자

StringBuffer클래스의 인스턴스를 생성할 때, 적절한 길이의 byte형 배열이 생성되고
이 배열은 문자열을 저장하고 편집하기 위한 공간(buffer) 으로 사용된다.

다음 예제로 살펴보자.

StringBuffer sb = new StringBuffer();
System.out.println(sb.capacity());  //  16

StringBuffer sb2 = new StringBuffer("hi");
System.out.println(sb2.capacity()); //  18

StringBuffer sb3 = new StringBuffer(30);
System.out.println(sb3.capacity()); //  30
  • 디폴트 생성자로 호출하면 기본적으로 배열의 사이즈는 16으로 지정된다.
  • 특정 문자열을 넘기면 문자열 길이 + 16 만큼으로 계산된 배열의 사이즈가 결정된다.
  • 생성 시 버퍼의 크기를 지정할 수도 있다.

StringBuffer 변경

String과 다르게 StringBuffer는 내용을 변경할 수 있다.

StringBuffer sb = new StringBuffer("hello");
0 1 2 3 4
h e l l o 

StringBuffer를 생성하고, sb에 문자열 "123"을 연결해보자.

sb.append("123");
0 1 2 3 4 5 6 7
h e l l o 1 2 3

hello뒤에 이어서 "123"이 추가된다.
append()는 반환타입이 StringBuffer인데 자기 자신을 반환한다.

StringBuffer sb2 = sb.append("world");
System.out.println(sb);     //  hello123world
System.out.println(sb2);    //  hello123world

그 결과 sb와 sb2가 같은 StringBuffer 인스턴스를 가리킨다는 것을 확인할 수 있다.
따라서, 아래와 같이 체인 형태로 사용할 수도 있다.

StringBuffer sb = new StringBuffer("hello");
sb.append("123")
        .append("world");

StringBuffer 비교

StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb == sb2);          //  false
System.out.println(sb.equals(sb2));     //  false

StringBuffer 클래스는 equals 메소드를 오버라이딩 하지 않았다.
그래서 equals를 사용해도 등가비교연산자(==)로 비교한것과 같은 결과를 얻는다.

String s = sb.toString();
String s2 = sb2.toString();

System.out.println(s.equals(s2));

toString()은 오버라이딩 되어있기 때문에 toString()을 호출하면 String을 반환한다.
그래서 StringBuffer를 비교하기 위해 toString()을 호출한 뒤 String 끼리 비교해야한다.


StringBuffer 메소드

StringBuffer 클래스의 메소드에 대해 알아보자. String과 중복되는 내용은 넘어가겠다.

StringBuffer append()

StringBuffer sb = new StringBuffer("hello");
sb.append('w')
        .append(10.0f)
        .append(123)
        .append("world");
System.out.println(sb);     //  hellow10.0123world
  • 매개변수로 입력된 값을 문자열로 변환하여 StringBuffer 문자열 뒤에 이어붙임.

int capacity()

StringBuffer sb = new StringBuffer(100);
System.out.println(sb.capacity());      //  100
  • StringBuffer 인스턴스의 버퍼크기 반환.

int capacity()

StringBuffer sb = new StringBuffer("hello");
System.out.println(sb.length());    //  5
  • StringBuffer 인스턴스에 저장되어있는 문자열의 길이를 반환.

StringBuffer delete(int start, int end)

StringBuffer sb = new StringBuffer("0123456");
sb.delete(2, 6);
System.out.println(sb);     //  016
  • 시작위치부터 끝 위치 사이에 있는 문자를 제거한다.
  • 끝 위치의 문자는 범위에서 제외 (start <= x < end)

StringBuffer insert(int pos, Object obj)

StringBuffer sb = new StringBuffer("0123456");
sb.insert(2, "hello");
System.out.println(sb);     //  01hello23456
  • 지정된 위치 (pos)에 두 번째 매개변수로 받은 값을 문자열로 변환하여 추가한다.

StringBuffer replace(int start, int end, String str)

StringBuffer sb = new StringBuffer("0123456");
sb.replace(3, sb.length(), "9999");
System.out.println(sb);     //  0129999
  • 지정된 범위 (start ~ end)의 문자들을 주어진 문자열로 변경
  • 끝 위치의 문자는 범위에서 제외 (start <= x < end)

StringBuffer reverse()

StringBuffer sb = new StringBuffer("0123456");
sb.reverse();
System.out.println(sb);     //  6543210
  • 문자열의 순서를 거꾸로 나열

StringBuilder란?

StringBuffer멀티쓰레드에 안전(thread safe)하도록 동기화되어 있다.
멀티쓰레드가 아닌 싱글쓰레드 환경에서는 StringBuffer의 동기화는 불필요하게 성능을 떨어뜨린다.
그래서 StringBuffer에서 쓰레드의 동기화를 뺀 StringBuilder가 새로 추가되었다.

싱글쓰레드 환경에서는 StringBuilder가 StringBuffer보다 성능이 뛰어나다.
StringBuffer와 StringBuilder는 완전히 똑같은 기능으로 작성되어 있기 때문에
필요하다면 아래와 같이 소스코드를 간단하게 변경할 수 있다.

StringBuffer sb = new StringBuffer();
sb.append("hi");

StringBuilder sb = new StringBuilder();
sb.append("hi");

정리

String : 문자열 연산이 적고 멀티쓰레드 환경, 자주 조회(참조)하는 경우
StringBuffer : 문자열 연산이 많고 멀티쓰레드 환경
StringBuilder : 문자열 연산이 많고 싱글쓰레드 환경이거나 동기화 고려하지 않을 경우


References

profile
얍얍 개발 펀치

0개의 댓글