본문 바로가기

프로그래밍 언어/자바

[Java] String & StringBuilder & StringBuffer

String은 char의 연속된 나열이다. java에서 String 클래스의 인스턴스는 불변한 객체이기 때문에 수정이 불가하다. 이러한 특징을 보완하기 위해 StringBuffer or StringBuilder를 함께 사용한다.

 

void concat1(String s1,String s2){
        s1 = s1 + s2;
}

void concat2(StringBuilder sb1, String s2){
        sb1.append(s2);
}

void concat3(StringBuffer sb2, String s2){
    sb2.append(s2);
}
    
void test(){
    String hello = "hello";
    String world = "world";

    concat1(hello,world);
    System.out.println(hello); // hello

    StringBuilder stringBuilder = new StringBuilder("hello");
    concat2(stringBuilder,world);
    System.out.println(stringBuilder); // helloworld

    StringBuffer stringBuffer = new StringBuffer("hello");
    concat3(stringBuffer,world);
    System.out.println(stringBuffer); // helloworld
}

 

  • concat1 : “hello”라는 String 클래스의 인스턴스를 인자로 넘겨주었으며, 해당 인자와 “world”를 더하는 연산을 수행하고, 결과값을 인자값에 재할당하였다. 하지만, hello 변수는 변하지 않았다. 메서드의 인자로 넘겨준 것은 immutable하기 때문에, String + String 연산으로 생성된 값은 새로운 인스턴스이며, “hello” String 래퍼런스와는 다른 것이다.
  • concat2, concat3 : StringBuilder와 StringBuffeer는 mutable하기 때문에 가지고 있는 String 값이 변경되었다.
  • String의 값을 변경해야될 경우 String이 아닌 StringBuilder와 StringBuffer를 사용하면 된다.

 

StringBuffer vs StringBuilder

위 클래스 중 먼저 나온 것은 StringBuffer이다. Java 1.4까지는 StringBuffer가 사용되었지만, public 멤버 메서드가 synchronized하게 구현되어 있어(StringBuffer는 Thread-safety함) 낮은 성능을 갖는다는 단점을 보완하기 위해, Java 1.5에 StringBuilder가 추가되었다.

 

만약 싱글 쓰레드 환경에서 사용하거나 thread-safety기능이 불필요할 경우 StringBuilder가 적합하다. 그 외에 Thread-safety가 필요하다면, StringBuffer가 적합하다.

 

성능 비교

void test(){
        System.gc();
        long start = System.currentTimeMillis();
        long startMemory = Runtime.getRuntime().freeMemory();

//        StringBuffer sb = new StringBuffer();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < 1000000; i++) sb.append(":").append(i);
        long end = System.currentTimeMillis();
        long endMemory = Runtime.getRuntime().freeMemory();
        System.out.println("Time taken: " + (end-start));
        System.out.println("Memory Used: " + (startMemory-endMemory));
}
  Time Memory
StringBuffer 47 37,636,144
StringBuilder 36 37,636,144

 

메모리 사용량은 동일하지만, StringBuilder가 StringBuffer보다 더 빠르다는 것을 확인하였다.(싱글 쓰레드 환경)

 

사용 팁

  • 프로그램 전역에서 “문자열”이 constant하게 사용될 경우, String 클래스를 사용하여 immutable한 객체를 사용한다.
  • “문자열”이 수정될 수 있고, 싱글 쓰레드 환경에서 접근된 다면, StringBuilder를 사용한다.
  • “문자열”이 수정될 수 있고, 멀티 쓰레드 환경에서 접근된 다면, StringBuffer를 사용한다.

 

- 참고자료

String vs StringBuilder vs StringBuffer in Java - GeeksforGeeks

String vs StringBuffer vs StringBuilder | DigitalOcean