StringBuilder는 문자열을 변경하거나 추가할 때 사용하는 클래스이다.
String은 한 번 생성된 문자열을 직접 변경할 수 없는 불변(immutable) 객체이기 때문에 문자열을 자주 수정해야 한다면 StringBuilder를 사용하는 것이 효율적이다.
특히 문자열을 반복해서 연결하거나 수정할 때 새로운 String 객체를 계속 생성하는 것보다 메모리와 성능 측면에서 유리하다.
StringBuilder는 문자열을 저장하기 위해 버퍼(Buffer)라는 공간을 사용한다.
StringBuilder sb = new StringBuilder();
기본 버퍼 크기는 16개의 문자를 저장할 수 있다.
StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity());
실행 결과:
16
버퍼의 공간이 부족해지면 StringBuilder가 자동으로 버퍼 크기를 늘린다.
원하는 크기의 버퍼를 미리 지정할 수도 있다.
StringBuilder sb = new StringBuilder(50);
위 코드는 50개의 문자를 저장할 수 있는 버퍼를 생성한다.
System.out.println(sb.capacity());
실행 결과:
50
버퍼 크기를 미리 지정하면 문자열의 크기를 어느 정도 예상할 수 있는 경우 불필요한 버퍼 확장을 줄일 수 있다.
문자열을 초기값으로 지정할 수도 있다.
StringBuilder sb = new StringBuilder("Hello");
"Hello"가 버퍼의 초기 문자열로 저장된다.
System.out.println(sb);
실행 결과:
Hello
이때 기본 버퍼 크기인 16에 문자열의 길이가 더해져 초기 용량은 21이 된다.
StringBuilder를 이해하기 위해서는 스레드(Thread)의 개념도 알아야 한다.
싱글스레드(Single Thread)는 하나의 프로세스에서 하나의 스레드가 작업을 수행하는 방식이다.
프로세스
↓
스레드 1
↓
작업 수행
하나의 작업 흐름으로 프로그램이 실행된다.
멀티스레드(Multi Thread)는 하나의 프로세스에서 둘 이상의 스레드가 작업을 수행하는 방식이다.
프로세스
├─ 스레드 1
├─ 스레드 2
└─ 스레드 3
여러 스레드가 동시에 작업하거나 실행 흐름을 나누어 작업할 수 있다.
StringBuilder와 비슷한 클래스로 StringBuffer가 있다.
두 클래스 모두 문자열을 변경할 수 있는 가변(Mutable) 문자열 클래스이다.
| 구분 | StringBuilder | StringBuffer |
|---|---|---|
| 문자열 변경 | 가능 | 가능 |
| 멀티스레드 환경 | 적합하지 않음 | 안전하게 사용 가능 |
| 동기화 | 지원하지 않음 | 지원 |
| 속도 | 상대적으로 빠름 | 상대적으로 느림 |
| 주 사용 환경 | 싱글스레드 | 멀티스레드 |
StringBuffer는 동기화(Synchronization)를 지원하기 때문에 여러 스레드가 동시에 접근하는 상황에서도 안전하게 사용할 수 있다.
반면 StringBuilder는 동기화를 지원하지 않는 대신 동기화에 따른 오버헤드가 없어 싱글스레드 환경에서 더 빠르게 사용할 수 있다.
싱글스레드 → StringBuilder
멀티스레드 → StringBuffer
다만 실제 프로그램에서는 멀티스레드 환경이라고 해서 무조건 StringBuffer를 사용하는 것은 아니며, 공유 문자열에 대한 동시 접근이 필요한지 등을 고려해야 한다.