JAVA StringBuffer

Dev.Shinny·2022년 9월 30일
0

자바의 정석

목록 보기
15/18

StringBuffer

내부적으로 문자열 편집을 위한 버퍼(buffer)를 가지고 있으며, StringBuffe 인스턴스를 생성할 때 그 크기를 지정할 수 있다.(mutable)

String 클래스는 인스턴스를 생성할 때, 문자열을 변경할 수 없지만 StringBuffer 클래스는 변경이 가능하다.

StirngBuffer 인스턴스를 생성할 때는 생성자 StringBuffer(int length)를 사용해서 StringBuffer 인스턴스에 저장될 문자열의 길이를 고려하여 충분이 여유있는 크기로 지정하는 것이 좋다. StringBuffer 인스턴스를 생성할 때, 버퍼의 크기를 지정해주지 않으면 16개의 문자를 저장할 수 있는 크기의 버퍼를 생성한다.

(1) StringBuffer() 
	16문자 담을 수 있는 버퍼를 가진 인스턴스 생성 
StringBuffer sb = new StringBuffer();


(2) StringBuffer(int length) 
	지정된 개수의 문자를 담을 수 있는 버퍼를 가진 인스턴스 생성
StringBuffer sb = new StringBuffer(10); 

(3) StringBuffer(String str)
	지정된 문자열 값을 갖는 인스턴스 생성
StringBuffer sb = new StringBuffer("Hi"); 

immutable vs mutable

String 클래스는 한 번 인스턴스가 생성되면 그 값을 변경할 수 없는 불변(immutable) 클래스이고, StringBuffer 클래스는 자유롭게 인스턴스 값을 변경할 수 있는 가변(mutable) 클래스이다.

불변 클래스를 사용하는 이유는 멀티 스레드 환경에서 객체가 변화되는 상황이라면 불변 인스턴스를 사용하는 것이 좀 더 신뢰도 높은 코드를 작성할 수 있기 때문이다. 하나의 객체에 접근하면서 각각 객체가 서로 영향을 주어서는 안 되는 경우에 불변 인스턴스를 사용하면 값이 변하지 않는다는 점이 보장된다.

반면 덧셈 연사자를 이용해 String 인스턴스 문자열을 결합하면, 내용이 합쳐진 새로운 String 인스턴스를 생성한다. 따라서 문자열 결합, 변경 등이 잦을 때 불변 클래스를 이용하면 메모리 낭비가 많아지고 속도 또한 매우 느려지므로 이럴 땐, 가변 클래스를 사용하는 것이 적절하다.

StringBuffer의 변경

(1)
StringBuffer sb = new StringBuffer("abc");
(2)
sb.append("123");
(3)
StringBuffer sb2 = sb.append("ZZ");

append()는 반환타입이 StringBuffer이며 자신의 주소를 반환한다. (3)이 수행되면, sb에 새로운 문자열이 추가되고 sb자신의 주소를 반환하여 sb2에 sb주소인 0x100이 저장된다.

(1)
StringBuffer sb = new StringBuffer("abc");
sb.append("123");
sb.append("ZZ");

(2) 
StringBuffer sb = new StringBuffer("abc");
sb.append("123").append("ZZ");

sb와 sb2 모두 같은 StringBuffer 인스턴스를 가리키고 있으므로 같은 내용이 출력된다. 그래서 하나의 StringBuffer 인스턴스에 대해 (2) 코드와 같이 연속적으로 append()를 호출하는 것이 가능하다.

StringBuffer의 비교

String 클래스에서는 equals가 오버라이딩되어 있어 문자열의 내용을 비교하도록 구현되어 있지만, StringBuffer 클래스는 오버라이딩되어 있지 않아 equals 메서드를 사용해서 등가비교연산자(==)로 비교한 것과 같은 결과를 얻는다.

StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");

System.out.println(sb==sb2); 		// false
System.out.println(sb.equals(sb2)); // false

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

Sytem.out.println(s.equals(s2));	// true

반면 toString()은 오버라이딩되어 있어 StringBuffer 인스턴스에 toString()을 호출하면, 담고 있는 문자열을 Stringㅇ로 반환한다. StringBuffer 인스턴스에 담긴 문자열을 비교하기 위해서는 toString()을 호출해서 String 인스턴스를 얻은 다음, 여기에 equlas 메서드를 사용해서 비교해야 한다.

StringBuffer 메서드

⭐️StringBuffer append(매개변수)

< 매개변수로 입력된 값을 문자열로 변환하여 
  StringBuffer 인스턴스가 저장하고 있는 문자열의 뒤에 덧붙인다.>

StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = sb.append(true);
sb.append('d').append(10.0f);
StringBuffer sb3 = sb.append("ABC").append(123);

// sb,sb2,sb3 = "abctrued10.0fABC123"

⭐️int capacity()

< StringBuffer 인스턴스의 버퍼크기를 알려준다.
  length()는 버퍼에 담긴 문자열의 길이를 알려준다. >

StringBuffer sb = new StringBuffer(100);
sb.append("abcd");
int bufferSize = sb.capacity(); // bufferSize = 100
int stringSize = sb.length();	// stringSize = 4

⭐️StringBuffer delete(int start, intend)
StringBuffer deleteCharAt(int index)

< 시작 위치(start)부터 끝 위치(end) 사이에 있는 문자를 제거한다.
  단 끝 위치의 문자는 제외 > 

StringBuffer sb = new StringBuffer("abcdefgh");
StringBuffer sb2 = sb.delete(3,6); // sb2 = "abcgh"

< 지정된 위치(index)의 문자를 제거한다. > 
StringBuffer sb = new StringBuffer("abcdefgh");
sb.deleteCharAt(2);	// sb = "abdefgh"

⭐️String insert(int pos, 매개변수)

< 두 번째 매개변수로 받은 값을 문자열로 변환하여 지정된 위치(pos)에 추가한다.
  pos는 0부터 시작. >
StringBuffer sb = new StringBuffer("0123456");
char [] crr = {'H','i'};
sb.insert(4,'.'); // "0123.456"
sb.insert(2,"A"); // "01A23.456"
sb.insert(0,crr); // "Hi01A23.456"

⭐️StringBuffer reverse()

< StringBuffer 인스턴스에 저장되어 있는 문자열의 순서를 거꾸로 나열한다. >

StringBuffer sb = new StringBuffer("0123456");
sb.reberse(); // sb = "6543210"

StringBuffer replae(int start, int end)

< 지정된 범위(start~end)의 문자들을 주어진 문자열로 바꾼다.
end위치의 문자는 범위에 포함되지 않는다.>

StringBuffer sb = new StringBuffer("abcdefg");
sb.replace(2,5,"CDE"); // sb = "abCDEfg"

void setLength(int newLength)

< 지정된 길이로 문자열의 길이를 변경한다. 
길이를 늘리는 경우 나버지 빈 공간은 '\u0000'로 채운다.>

StringBuffer sb = new StringBuffer("abcdefg");
sb.setLength(5); // sb = "abcde"

StringBuffer sb2 = new StringBuffer("abcdefg");
sb2.setLength(10); // sb2 = "abcdefg    "

< 문자열을 초기화 할 때 사용할 수 있음 > 
sb2.setLength(0);

StringBuilder

StringBuffer 멀티쓰레드에 안전(thread safe)하도록 동기화되어 있다. 동기화는 StringBuffer의 성능을 떨어뜨린다. 멀티쓰레드로 작성된 프로그램이 아닌 경우, StringBuffer의 동기화는 불필요하게 성능만 떨어뜨리게 된다.

StringBuilder는 StringBuffer에서 쓰레드의 동기화를 뺀 것.

StringBuffer와 StringBuilder는 완전히 똑같은 기능으로 작성되어 있어, 소스코드에서 StringBuffer 대신 StringBuilder를 사용하도록 바꾸기만 하면 된다.

즉, 단일 쓰레드 경우 StringBuilder를 사용하는 편이 좋다.

profile
Hello I'm Shinny. A developer who try to enjoy the challenge.

0개의 댓글