자바의 정석[기초편]으로 공부한 내용을 정리한 글입니다.
StringBuffer 클래스
StringBuffer 클래스는 문자열을 다룰 때 내용을 자유롭게 변경할 수 있도록 설계된 클래스입니다.
기존의 String 클래스는 한번 생성되면 그 내용을 바꿀 수 없는(immutable) 클래스였습니다. 즉, 문자열을 연결하거나 일부만 바꾸고 싶어도 새로운 문자열 객체를 다시 생성해야 했습니다.
→ StringBuffer는 이러한 단점을 보완하여 내용을 바꾸더라도 새로운 객체를 만들지 않고 기존의 객체에서 직접 변경이 가능합니다.
내부 구조
public final class StringBuffer implements java.io.Serializable {
private char[] value;
...
}
- 내부적으로 문자열을 char[] value 배열로 저장합니다.
- 이 배열을 통해 문자열을 직접 변경할 수 있습니다.
- 따라서 효율적으로 문자열을 조작할 수 있습니다.
StringBuffer 생성자
StringBuffer 클래스는 여러 생성자를 제공하여 다양한 방식으로 초기화할 수 있습니다.
생성자 종류
- StringBuffer(int length)
public StringBuffer(int length) {
value = new char[length];
shared = false;
}
- length 크기의 문자 배열을 생성합니다.
- 내부에서 문자열을 저장할 공간을 미리 확보합니다.
- StringBuffer()
public StringBuffer() {
this(16);
}
- 기본 생성자입니다.
- 버퍼의 초기 크기를 16으로 설정합니다.
- 즉, 내부 배열은 new char[16]으로 생성됩니다.
- StringBuffer(String str)
public StringBuffer(String str) {
this(str.length() + 16);
append(str);
}
- 문자열 str의 길이보다 16만큼 더 큰 크기의 버퍼를 생성하고,
- str의 내용을 내부 버퍼에 복사합니다.
- 문자열 내용을 가진 StringBuffer 객체를 만들고자 할 때 자주 사용됩니다.
버퍼 크기 확장 방식
문자열이 계속 추가되다 보면 처음에 만든 char[]의 길이를 초과할 수 있습니다.
이 경우 Java는 다음과 같은 방식으로 버퍼를 자동으로 확장합니다.
char[] newValue = new char[newCapacity];
System.arraycopy(value, 0, newValue, 0, count);
value = newValue;
- 새로운 배열(newCapacity)을 만들고,
- 기존의 내용을 복사해서 저장한 후,
- 내부 배열 value를 이 새 배열로 바꿉니다.
이 과정을 통해 기존의 StringBuffer 객체는 새로운 내용을 담을 수 있게 됩니다.
StringBuffer의 변경
StringBuffer는 문자열을 직접 수정할 수 있다
StringBuffer sb = new StringBuffer("abc");
- StringBuffer 객체 sb를 "abc"로 초기화했습니다.
- 내부적으로는 char[] 배열에 a, b, c가 들어가 있으며,
- 배열의 크기는 기본 생성자의 특성상 여유 공간을 갖고 생성됩니다.
문자열 추가 (append())
sb.append("123");
- 문자열 "123"을 기존 "abc" 뒤에 연결(append) 합니다.
- StringBuffer는 내부 배열에 이 내용을 추가하기 때문에 기존 객체의 주소는 그대로입니다.
- 결과적으로 sb는 "abc123"이 됩니다.
연속적인 append 사용
StringBuffer sb2 = sb.append("ZZ");
sb.append("ZZ");
sb2 = sb; // 같은 객체를 참조
- append()는 StringBuffer 자기 자신을 반환하기 때문에, 위 코드는 다음과 같습니다:
- 그래서 sb2도 "abc123ZZ"이 되고, sb와 sb2는 동일한 객체를 가리키는 것입니다.
중요한 요약
- StringBuffer는 내부 내용을 직접 바꾸므로 append() 해도 새로운 객체를 만들지 않습니다.
- 따라서 메서드 체이닝이 가능하며, 아래처럼 한 줄로 이어붙일 수 있습니다:
new StringBuffer("abc").append("123").append("ZZ");
StringBuffer의 비교
equals() 비교 (객체 비교)
StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb.equals(sb2)); // false
- StringBuffer 클래스는 equals()를 재정의(override) 하지 않았기 때문에,
- Object의 기본 equals() 메서드가 호출되어 주소 비교가 일어납니다.
- 따라서 내용이 같아도 주소가 다르면 false가 됩니다.
toString() 후 문자열 비교
String s = sb.toString();
String s2 = sb2.toString();
System.out.println(s.equals(s2)); // true
- toString()을 호출하면 StringBuffer가 가지고 있는 문자열을 String으로 변환합니다.
- String 클래스는 equals()가 문자열의 내용을 비교하므로, "abc" == "abc" → true.
예제
StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println("sb == sb2 ? " + (sb == sb2)); // false (주소 다름)
System.out.println("sb.equals(sb2) ? " + sb.equals(sb2)); // false (equals는 주소 비교)
String s = sb.toString();
String s2 = sb2.toString();
System.out.println("s.equals(s2) ? " + s.equals(s2)); // true (내용 비교)
정리
비교 방식 | 클래스 | 결과 |
== | StringBuffer | 주소 비교 → false |
equals() | StringBuffer | 주소 비교 → false |
toString().equals() | String | 문자열 내용 비교 → true |
'Java' 카테고리의 다른 글
오토박싱 & 언박싱 (0) | 2025.06.22 |
---|---|
래퍼(wrapper) 클래스 (0) | 2025.06.22 |
문자열과 기본형 간의 변 (0) | 2025.06.22 |
String클래스 (0) | 2025.06.22 |
Object클래스 메서드 - toString() (0) | 2025.06.22 |