이것저것 적어보는 블로그

[Java] String, StringBuilder, StringBuffer의 차이 본문

개발&코딩/Java

[Java] String, StringBuilder, StringBuffer의 차이

dona0408 2023. 1. 27. 11:45
반응형

Java에서 문자열을 다루는 대표적인 클래스로 String, StringBuilder, StringBuffer가 있다.

연산이 많지 않거나, 단일스레드, 단순한 사용 시엔 세 가지 클래스 어떤 걸 사용하여도 큰 문제가 없는데

반복적인 연산 횟수가 증가하거나, 멀티스레드, Race Condition 등의 상황이 빈번히 발생하면 클래스의 특성에 맞게 사용하는 것이 좋다.

 

1) String

String은 다른 두 클래스와는 다르게 Immutable(불변)이다.

String 객체는 한번 생성되면 할당된 메모리 공간의 변화가 없다.

+ 연산과 concat 메서드의 동작 방식을 보면

'기존 문자열 + 새 문자열'의 방식이 아닌, 새로운 String 객체를 생성한 후 새 String 객체에 연결된 문자열을 저장하고 참조하도록 하는 것이다. 아래의 코드를 보면 이해가 쉽게 될 것이다.

String str1 = "str1";
String str2 = "str2";
String str3 = str1 + str2; // 결과: str1str2

// 내부적으로 실행되는 코드
String str3 = new StringBuffer().append(str1).append(str2).toString();

String 클래스 객체는 Heap영역에 생성되며 한번 생성된 내부 객체의 내부 내용을 변화시킬 수 없다.

자바는 new연산이 많아질수록 성능에 영향을 주므로, 문자열 연산이 많은 경우 String은 피하는 게 좋다!!

대신에 Immutable 하기에 간단하게 사용하기 좋고, 동기화에 신경 쓰지 않아도 된다. (Thread-safe)

 

2) StringBuffer와 StringBuilder

StringBuffer와 StringBuilder는 String과 다르게 mutable(가변)이다.

기존 생성된 객체의 버퍼 크기를 늘이고 줄이며 유연하게 동작한다.

또, StringBuffer와 StringBuilder 클래스가 제공하는 메서드는 동일하다.

이렇게 보면 두 클래스가 별 차이가 없는 거 같지만, 가장 큰 차이는 동기화의 유무다.

 - StringBuffer는 동기화 키워드를 지원해서 멀티스레드 환경에서 안전 (Thread-Safe)

 - StringBuilder는 동기화를 지원하지 않기 때문에 값 보장이 안된다. 
    대신 단일 스레드에서의 성능은 StringBuilder가 StringBuffer보다 뛰어나다.

 

3) String과 StringBuffer의 연산 속도 비교

public class Test {
    public static void main(String[] args) {
        // (1) String의 +연산을 이용해서 10,000개의 *를 이어붙입니다.
        //시작시간을 기록합니다.(millisecond단위)
        long startTime1 = System.currentTimeMillis();
        String str="";
        for(int i=0;i<10000;i++){
            str=str+"*";
        }
        //종료시간을 기록합니다.(millisecond단위)
        long endTime1 = System.currentTimeMillis();

        // (2) StringBuffer를 이용해서 10,000개의 *를 이어붙입니다.
        //시작시간을 기록합니다.(millisecond단위)
        long startTime2 = System.currentTimeMillis();
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<10000;i++){
            sb.append("*");
        }
        //종료시간을 기록합니다.(millisecond단위)
        long endTime2 = System.currentTimeMillis();

        // 방법(1)과 방법(2)가 걸린 시간을 비교합니다.
        long duration1 = endTime1-startTime1;
        long duration2 = endTime2-startTime2;

        System.out.println("String의 +연산을 이용한 경우 : "+ duration1);
        System.out.println("StringBuffer의 append()을 이용한 경우 : "+ duration2);
    }
}

 

문자열 연산이 적거나, 짧은 문자열을 더할 경우 -> String

 

문자열 연산이 많거나, 멀티스레드, Thread-Safe 프로그램 -> StringBuffer

 

문자열 연산이 많거나, 스레드의 안전/동기화 여부가 상관없는 경우 -> StringBuilder

 

그동안은 그냥 String만 써왔는데, 앞으로는 조금 더 생각하고 사용하게 될 것 같다.

 

참고

https://12bme.tistory.com/42

https://velog.io/@heoseungyeon/StringBuilder와-StringBuffer는-무슨-차이가-있는가

https://school.programmers.co.kr/learn/courses/9/lessons/254

https://dkswnkk.tistory.com/584

반응형

'개발&코딩 > Java' 카테고리의 다른 글

자바 환경변수 설정하기  (0) 2018.12.31
Comments