Java 문자열 클래스 정리 — String, StringBuilder, StringBuffer

gustjtmd·2025년 4월 13일

1. 문자열은 왜 중요한가?

프로그래밍을 할 때 문자열(String) 은 가장 기본적이면서도 많이 쓰이는 자료형이다.
Java는 문자열을 효율적으로 다루기 위해

  • String
  • StringBuilder
  • StringBuffer
    세 가지 주요 클래스를 제공한다.

이들은 메모리 구조와 동작 방식이 다르기 때문에, 상황에 따라 적절히 선택해야 한다.


2. String, StringBuilder, StringBuffer 차이

클래스특징메모리 구조쓰레드 안전성(Thread Safety)
String불변(Immutable) 객체Heap에 새로운 객체 생성안전 (Thread-Safe)
StringBuilder가변(Mutable) 객체내부 char 배열 수정안전하지 않음 (싱글 스레드 권장)
StringBuffer가변(Mutable) 객체내부 char 배열 수정안전 (멀티 스레드 지원)

핵심 차이 요약

  • String : 변경할 때마다 새로운 객체를 생성한다.
    → 메모리 소모가 크지만, 안정적이고 직관적이다.

  • StringBuilder : 문자열 수정이 많을 때 빠르다.
    → 싱글 스레드 환경에서 추천.

  • StringBuffer : StringBuilder와 거의 같지만, 동기화(synchronized) 되어 있어 멀티스레드에서도 안전하다.


3. 예제 코드 비교

// String
String str = "Hello";
str += " World";  // 새로운 객체 생성

// StringBuilder
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");  // 기존 객체 수정

// StringBuffer
StringBuffer sbf = new StringBuffer("Hello");
sbf.append(" World"); // 기존 객체 수정 + 동기화

4. String 클래스 - 자주 쓰는 메소드

메소드설명예시
length()문자열 길이 반환"hello".length()5
charAt(int index)특정 인덱스의 문자 반환"hello".charAt(1)'e'
substring(int start, int end)부분 문자열 추출"hello".substring(1, 4)"ell"
indexOf(String str)문자열 내 검색"hello".indexOf("e")1
equals(Object obj)문자열 비교"hello".equals("hello")true
toUpperCase()대문자로 변환"hello".toUpperCase()"HELLO"
toLowerCase()소문자로 변환"HELLO".toLowerCase()"hello"
trim()앞뒤 공백 제거" hello ".trim()"hello"
replace(CharSequence old, CharSequence new)문자열 치환"hello".replace("e", "a")"hallo"

활용 포인트

  • substring, replace 같은 메소드는 새로운 객체를 반환한다.
  • charAt, indexOf원본 객체를 복사하지 않고 바로 결과를 반환한다 (빠름).

5. StringBuilder 클래스 - 자주 쓰는 메소드

메소드설명예시
append(String str)문자열 끝에 추가sb.append("World")
insert(int offset, String str)특정 위치에 삽입sb.insert(5, " Java")
replace(int start, int end, String str)범위 치환sb.replace(0, 5, "Hi")
delete(int start, int end)범위 삭제sb.delete(0, 2)
reverse()문자열 반전sb.reverse()
toString()String으로 변환sb.toString()

StringBuilder 주요 특징

  • append 연산이 가장 많다 (StringBuilder는 누적해서 추가할 때 최적).
  • insert, delete, replace 메소드도 메모리 재할당 없이 동작한다.
  • reverse는 알고리즘 문제에서 종종 유용하다.
StringBuilder sb = new StringBuilder("hello");
sb.append(" world");            // hello world
sb.insert(5, " JAVA");           // hello JAVA world
sb.replace(6, 10, "Python");     // hello Python world
sb.delete(5, 12);                // hello world
sb.reverse();                   // dlrow olleh
System.out.println(sb.toString());

6. 자료구조 관점 요약

  • String: 내부에 char[] 배열을 가지고 있고,
    한 번 생성되면 내용을 바꿀 수 없는 불변 객체이다.

    ➔ 값이 바뀌면 새로운 객체를 생성한다. → Heap 메모리 소모 증가.

  • StringBuilder, StringBuffer:
    내부에 char[] 배열과 동적 크기 조정 로직이 있다.

    ➔ 수정이 발생해도 기존 버퍼를 직접 수정한다.
    ➔ 용량(capacity)이 다 차면 버퍼 크기를 2배 확장한다. (ArrayList와 유사)


7. 상황별 추천

상황추천 클래스
문자열 변경이 거의 없음String
문자열 수정이 빈번함 (단일 쓰레드)StringBuilder
문자열 수정이 빈번함 (멀티 쓰레드)StringBuffer

최종 정리

  • String은 불변 객체로 안전하지만, 수정 시마다 새 객체를 만들어 비용이 크다.
  • StringBuilder는 빠른 수정이 가능하지만, 동기화는 없다.
  • StringBuffer는 수정은 느릴 수 있지만 멀티스레드 환경에서 안전하다.
  • 문자열 조작 성능을 높이려면 내부 자료구조(char[]), 메모리 재할당(capacity doubling)을 이해하고 선택해야 한다.
profile
반갑습니다

0개의 댓글