HIT해

StringBuilder를 사용해야하는 이유 본문

Java/CS

StringBuilder를 사용해야하는 이유

힛해 2025. 3. 28. 22:52
728x90

String의 불변성(Immutability)이란?

Java에서 String 객체는 불변(immutable)입니다. 즉, 한번 생성된 String 객체의 내용은 절대 변경될 수 없습니다. 

String 불변성의 오해: += 연산자

많은 Java 초보자들이 가지는 의문 중 하나는 "String이 불변이라면, 왜 += 연산자로 문자열을 이어붙일 수 있는가?"입니다.

String answer = "Hello";
answer += " World"; // answer = answer + " World" 와 동일
System.out.println(answer); // "Hello World" 출력

 

  1. 메모리에 "Hello" 문자열 객체가 생성
  2. 메모리에 " World" 문자열 객체가 생성
  3. 두 문자열을 합친 새로운 "Hello World" 문자열 객체가 메모리에 생성
  4. answer 변수가 새로운 "Hello World" 문자열 객체를 참조하도록 변경
  5. 원래의 "Hello" 문자열 객체는 변경되지 않고, 그대로 메모리에 남음

즉, 원래 String 객체의 내용이 변경되는 것이 아니라, 새로운 String 객체가 생성되고 변수의 참조만 바뀐다.

String 연산의 문제점

이러한 String의 불변성은 문자열 조작이 적을 때는 큰 문제가 되지 않지만, 다음과 같은 경우에 성능 문제를 일으킨다.

String result = ""; for (int i = 0; i < 10000; i++) 
{ result += i; // 매 반복마다 새 객체 생성! }

 

이 코드는 10,000개의 임시 String 객체를 생성하고 이는 메모리 낭비와 함께 성능 저하의 원인이 된다.

StringBuilder: 가변 문자열의 해결책

이러한 문제를 해결하기 위해 Java는 StringBuilder 클래스를 제공합니다.

StringBuilder는 내부적으로 가변(mutable)한 문자 배열을 사용하여 문자열을 효율적으로 조작할 수 있게 해줍니다.

반복적인 문자열 연결의 개선

StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000; i++) { 
sb.append(i); // 같은 객체를 수정, 새 객체 생성 안 함 
}
String result = sb.toString();

 

StringBuilder는 내부 버퍼를 가지고 있어 문자열을 추가할 때 새 객체를 생성하지 않고 기존 버퍼를 확장하거나 수정하기에 메모리 사용과 성능 측면에서 훨씬 효율적입니다.

StringBuilder 주요 메서드 사용법

StringBuilder는 다양한 문자열 조작 메서드를 제공합니다. 주요 메서드들을 실제 예제와 함께 살펴보겠습니다.

append() - 문자열 끝에 추가

append() 메서드는 StringBuilder의 가장 기본적인 메서드로, 현재 문자열의 끝에 인자로 전달된 값을 추가한다.

 
StringBuilder sb = new StringBuilder("Hello");
sb.append(" ");       // 공백 추가
sb.append("World");   // 문자열 추가
sb.append('!');       // 문자 추가
sb.append(2023);      // 숫자 추가
System.out.println(sb.toString());  // 출력: "Hello World!2023"
체이닝도 가능하다
 
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" ").append("World");

insert() - 지정한 위치에 삽입

insert() 메서드는 지정한 인덱스 위치에 문자열을 삽입한다.

StringBuilder sb = new StringBuilder("Hello World");
sb.insert(5, " Beautiful");  // 인덱스 5 위치에 삽입
System.out.println(sb.toString());  // 출력: "Hello Beautiful World"

// 다양한 타입 삽입 가능
sb.insert(0, "Say: ");      // 시작 위치에 삽입
sb.insert(sb.length(), "!"); // 끝에 삽입(append와 동일)

delete() 및 deleteCharAt() - 문자열 삭제

delete() 메서드는 지정한 시작 인덱스부터 끝 인덱스 직전까지의 문자를 삭제합니다. deleteCharAt()은 단일 문자를 삭제합니다.

StringBuilder sb = new StringBuilder("Hello Beautiful World");
sb.delete(6, 16); // 인덱스 6부터 15까지 삭제 
System.out.println(sb.toString()); // 출력: "Hello World" 
sb.deleteCharAt(5); // 인덱스 5의 문자(공백) 삭제 
System.out.println(sb.toString()); // 출력: "HelloWorld"
 
replace() - 문자열 교체

replace() 메서드는 지정한 범위의 문자열을 새로운 문자열로 교체합니다.

StringBuilder sb = new StringBuilder("Hello World"); 
sb.replace(6, 11, "Java"); // "World"를 "Java"로 교체 
System.out.println(sb.toString()); // 출력: "Hello Java"

reverse() - 문자열 뒤집기

reverse() 메서드는 전체 문자열을 뒤집습니다. 이는 String 클래스에서는 직접 제공하지 않는 기능입니다.

StringBuilder sb = new StringBuilder("Hello World"); 
sb.reverse(); System.out.println(sb.toString()); // 출력: "dlroW olleH"

문자열을 뒤집는 작업이 필요할 때, String 클래스만으로는 다음과 같이 수동으로 처리해야 합니다:

String original = "Hello"; 
char[] chars = original.toCharArray();
String reversed = ""; for (int i = chars.length - 1; i >= 0; i--) {
reversed += chars[i]; // 비효율적인 방식 
}