본문 바로가기
Team

[CS 스터디] String vs StringBuffer vs StringBuilder

by seungh2 2023. 9. 21.

자바에서 문자열을 다루는 대표적인 클래스

String, StringBuffer, StringBuilder


String은 불변

  • 기본적으로 String 객체의 값은 변경할 수 없다. = 불변 자료형

  • String에서 많이 사용하는 메소드를 보면 String 객체 자체가 변경되는 것이 아니라 새로 String 객체를 만들어서 반환해주는 것
public class Main {
    public static void main(String[] args) {
        String str = "abcdefg";
        System.out.println(str.toUpperCase());              // "ABCDEFG"
        System.out.println(str.substring(2));     // "cdefg"
        System.out.println(str);    // "abcdefg"
    }
}

String 값 할당 방법

  • literal 값을 대입하는 방법
    • Heap 메모리 영역 안에 있는 String constant pool에 저장된다. 
    • String constant pool에 존재하는 literal 값을 사용하게 된다면 새롭게 만드는 것이 아니라 현재 존재하는 값을 사용한다.
  • new 키워드를 사용하는 방법
    • Heap 메모리 영역 안에 동적으로 메모리 공간이 할당된다.
    • 즉, 같은 값이어도 다른 메모리 공간을 참조하게 된다.
public class Main {
    public static void main(String[] args) {
    	// literal 값으로 대입
        String str = "abc";
        // new 키워드 사용
        String abc = new String("abc");
    }
}

동등 비교

public class Main {
    public static void main(String[] args) {
        String str = "abc";
        String abc = "abc";
        String strN = new String("abc");
        String abcN = new String("abc");
        System.out.println(str == abc);             // true
        System.out.println(str == strN);            // false
        System.out.println(strN == abcN);           // false
        System.out.println(str.equals(abc));        // true
        System.out.println(str.equals(strN));       // true
        System.out.println(strN.equals(abcN));      // true
    }
}

StringBuffer / StringBuilder는 가변

  • 버퍼의 크기를 가변적으로 사용할 수 있다.
  • 두 클래스 모두 내부 Buffer에 문자열을 저장해두고 그 안에서 추가, 수정, 삭제 작업을 할 수 있다.
  • 즉, 동일 객체 내에서 문자열 크기를 변경하는 것이 가능하다.

동등 비교

  • StringBuffer / StringBuilder는 equals()메서드를 오버라이딩하지 않아 ==과 equals()의 결과가 같다.
  • 제대로 비교하고 싶다면, toString()으로 String 객체로 변환한 뒤에 equals() 비교를 해야 한다.

StringBuilder와 StringBuffer의 차이

  • Synchronization 동기화
  • StringBuilder는 동기화를 지원하지 않고 StringBuffer는 동기화를 지원한다. 
  • StringBuffer는 synchronized 키워드를 사용하여 동기화를 지원하기 때문에 멀티 스레드 환경에서도 안전하게 동작할 수 있다.
  • 하지만 단일 스레드 환경에서 사용할 때는 동기화 오버헤드가 없기 때문에 StringBuffer보다 StringBuilder가 더 높은 성능을 갖는다.
 synchronized 키워드
여러 개의 스레드가 한 개의 자원에 접근하려고 할 때, 현재 데이터를 사용하고 있는 스레드를 제외하고 나머지 스레드들이 데이터에 접근할 수 없도록 막는다.

문자열 합치기 성능 비교

  • 값이 변경될 때마다 새롭게 객체를 만드는 String 보다 StringBuffer나 StringBuilder가 훨씬 빠르게 동작한다.
  • 문자열의 추가, 수정, 삭제가 빈번하게 발생하는 경우라면 StringBuffer나 StringBuilder를 사용하는 것이 좋다.
사실 자바는 String 객체에서 + 연산을 사용하면, 컴파일 전에 내부적으로 StringBuilder를 사용하여 합친 후에 String 객체로 돌려준다. 
  • 그렇다면, String 객체로 합치는 것과 StringBuilder로 합치는 것이나 똑같을까?
  • 한 번만 한다면 그렇겠지만, 문자열을 합치는 연산을 많이 한다면 당연히 StringBuilder를 사용하는 것이 좋다.
  • String 객체로 합칠 때마다 새로운 StringBuilder로 합치고 String으로 바꿔서 돌려주는 것이기 때문에

변하지 않는 문자열을 다룰 때 : String
단일 스레드 환경에서 변경 가능한 문자열을 다룰 때 : StringBuilder
멀티 스레드 환경에서 변경 가능한 문자열을 다룰 때 : StringBuffer

728x90

댓글