StringBuilder와 텍스트 조립
불변 문자열을 반복해서 이어 붙이면 중간 문자열이 많이 만들어질 수 있습니다.
StringBuilder는 하나의 가변 버퍼에서 내용을 추가하고 바꾼 뒤 마지막에 String으로 변환합니다.
간단한 한 줄 연결은 컴파일러가 최적화하므로 무조건 바꿀 필요는 없습니다.
반복문이나 조건부 조립처럼 결합 횟수가 동적으로 늘어날 때 효과가 큽니다.
이 절에서는 성능뿐 아니라 구분자와 출력 형식을 읽기 좋게 만드는 방법을 살펴봅니다.
반복 결합에는 가변 버퍼를 쓴다
루프마다 text = text + part를 수행하면 이전 내용을 복사한 새 문자열이 생깁니다.
StringBuilder의 append는 같은 버퍼를 이어 사용합니다.
구분자는 원소 사이에만 넣는다
첫 원소 앞이나 마지막 원소 뒤에 불필요한 쉼표가 생기지 않도록 인덱스 조건을 두거나 StringJoiner, Collectors.joining을 고려합니다.
구분자를 원소 앞에 무조건 붙이면 결과의 맨 앞에 불필요한 쉼표가 생깁니다. 첫 원소인지 검사하거나 StringJoiner를 사용해 “원소 사이에만 구분자가 있다”는 출력 형식을 코드에 그대로 표현합니다.
import java.util.StringJoiner;
public class TextAssembly {
public static void main(String[] args) {
String[] names = {"Ada", "Linus", "James"};
StringBuilder builder = new StringBuilder();
for (int index = 0; index < names.length; index++) {
if (index > 0) builder.append(" | ");
builder.append(index + 1).append(':').append(names[index]);
}
System.out.println(builder);
StringJoiner joiner = new StringJoiner(", ", "[", "]");
for (String name : names) joiner.add(name);
System.out.println(joiner);
}
}원소가 0개, 1개, 여러 개인 배열을 차례로 넣어 앞뒤 구분자가 남지 않는지 확인해 보세요. 이 세 입력이 통과하면 반복 횟수보다 경계 조건을 올바르게 설계한 것입니다.
1:Ada | 2:Linus | 3:James
[Ada, Linus, James]StringBuilder는 자유 형식, StringJoiner는 구분자·접두사·접미사가 있는 목록에 적합합니다.
용량은 측정 뒤에 조정한다
예상 길이가 매우 분명하면 초기 용량을 줄 수 있지만 대부분은 기본 확장으로 충분합니다.
추측으로 용량 계산을 복잡하게 만들지 않습니다.
초기 용량은 성능 힌트일 뿐 문자열 길이 제한이 아니며 부족하면 자동으로 늘어납니다. 프로파일링에서 재할당이 실제 병목으로 확인되기 전에는 복잡한 길이 예측보다 기본 생성자를 선택하는 편이 읽기 쉽습니다.
StringBuilder builder = new StringBuilder("Java");
builder.append(' ').append(25);
builder.insert(0, "JDK ");
String result = builder.toString();// 여러 스레드가 같은 builder를 공유하지 않는다.
// 단순한 한 문장: String label = "count=" + count; 는 그대로 읽기 좋다.StringBuilder는 모든 +를 대체하는 도구가 아니라 반복적으로 변하는 텍스트 조립 과정을 명확히 표현하는 도구입니다.