String이 있는데 왜 StringBuilder인가?


82

나는 StringBuilder처음으로 만났고 Java가 이미 String추가를 허용 하는 매우 강력한 클래스를 가지고 있기 때문에 놀랐습니다 .

왜 2 String등석인가?

자세한 내용은 어디에서 확인할 수 있습니까 StringBuilder?



저는 이것이 실제로 한 번 저에게 인터뷰 질문으로 떠올랐다는 것을 주목하고 싶었습니다. 그들은 내가 큰 문자열을 채울 것이 무엇인지 물었다 .....
preOtep 19

답변:


171

String추가를 허용하지 않습니다. 에서 호출하는 각 메서드 String는 새 개체를 만들고 반환합니다. String불변 이기 때문 입니다. 내부 상태를 변경할 수 없습니다.

반면 StringBuilder에 변경 가능합니다. 호출 append(..)할 때 새 문자열 객체를 만드는 대신 내부 문자 배열을 변경합니다.

따라서 다음을 갖는 것이 더 효율적입니다.

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 500; i ++) {
    sb.append(i);
}

대신 str += i500 개의 새로운 문자열 객체를 생성합니다.

이 예에서는 루프를 사용합니다. helios가 주석에 언급했듯이 컴파일러 String d = a + b + c는 다음과 같은 표현식을 자동으로 번역합니다.

String d = new StringBuilder(a).append(b).append(c).toString();

이 있음을 유의하십시오 StringBuffer에 추가 StringBuilder. 차이점은 전자에는 동기화 된 메서드가 있다는 것입니다. 지역 변수로 사용하는 경우 StringBuilder. 그것은 여러 스레드에서 액세스 할 수하는 것이 가능하다는 발생하면 사용 StringBuffer(즉,의 희소)


24
+1. 다음을 추가 할 수 있습니다. "따라서 StrungBuilder가 성능을 찾습니다"및 "Java 컴파일러는 객체 생성 성능을 피하기 위해 A + B + C와 같은 표현식을 새로운 StringBuilder (A) .append (B) .append (C) .toString ()으로 대체합니다. penalties ":)
helios 2011 년

그리고 모두 대단히 감사합니다. 당신은 모두 +1을받을 자격이 있습니다 (즉시 전달 될 것입니다 :)
an00b 2011 년

'불변'객체의 회상과 비슷합니다.
Gary Tsui

훌륭한 반응. 그러나 내가 놓친 것은 컴파일러 가 for 루프를 포함하여 대부분의 시간 동안 Stringbuilder를 사용할 때를 파악할 수 없기 때문에 개발자로 생각할 필요가 없습니다. :)
worldsayshi

좋은 대답입니다. 이 줄을 추가하고 싶습니다. 문자열을 보유하는 배열 (즉, char [] 값)이 최종 선언되었지만 StringBuilder의 경우 문자열을 보유하는 배열 (즉, char [] 값)이 최종이 아니므로 문자열은 변경 불가능합니다. 당신은 모두 StringBuilder의 경우 문자열을 보유하고 배열의 변경 할 수 있습니다
디나 존

60

다음은 그 이유에 대한 구체적인 예입니다.

int total = 50000;
String s = ""; 
for (int i = 0; i < total; i++) { s += String.valueOf(i); } 
// 4828ms

StringBuilder sb = new StringBuilder(); 
for (int i = 0; i < total; i++) { sb.append(String.valueOf(i)); } 
// 4ms

보시다시피 성능의 차이가 중요합니다.


추신. Macbook Pro Dual 코어에서 실행했습니다.
Amir Raminfar 2011 년

이것은 이유를 설명하지 않습니다
Steve Kuo 2011 년

25
이것은 String이있을 때 왜 StringBuilder인가? 이것은 StringBuilder가 왜 그렇게 빠른지 설명하지 않습니다 . 그러나 그것은 질문이 아닙니다. 그래서 이것은 유효한 대답입니다.
Kerem Baydoğan 2011 년

2
@krmby-동의합니다. 이유에 대한 대답은 실제로 다른 질문을 의미합니다.
Amir Raminfar 2011 년

12
나는 비교를 공정하게 만들기 위해 s = sb.ToString();마지막에 a를 수행 할 시간을 포함해야 하므로 적어도 두 예제에서 동일한 작업을 수행했습니다 (결과는 a string).
Scott Whitlock 2012

19

String 클래스는 변경 불가능한 반면 StringBuilder는 변경 가능합니다.

String s = "Hello";
s = s + "World";

위의 코드는 String이 변경 불가능하기 때문에 두 개의 객체를 생성합니다.

StringBuilder sb = new StringBuilder("Hello");
sb.append("World");

위의 코드는 StringBuilder가 변경 불가능하지 않기 때문에 하나의 객체 만 생성합니다.

Lesson : String을 여러 번 조작 / 업데이트 / 추가 할 필요가있을 때마다 StringBuilder가 String에 비해 효율적으로 사용됩니다.


8

StringBuilder는 문자열 구축을위한 것입니다. 특히, 매우 성능이 좋은 방식으로 구축합니다. String 클래스는 많은 것들에 좋지만, 각각의 새로운 문자열은 완전히 새롭고 재 할당 된 문자열이기 때문에 작은 문자열 부분에서 새 문자열을 조립할 때 실제로 끔찍한 성능을 보입니다. ( 불변 ) StringBuilder는 동일한 시퀀스를 제자리에 유지하고 수정합니다 ( mutable ).


5

StringBuilder 클래스는 변경 가능하며 String과 달리 더 많은 String 객체를 만들 필요없이 문자열의 내용을 수정할 수 있습니다. 이는 문자열을 많이 수정할 때 성능 향상이 될 수 있습니다. 또한 동기화되는 StringBuffer라는 StringBuilder의 대응 물도 있으므로 다중 스레드 환경에 이상적입니다.

String의 가장 큰 문제는 모든 작업이 항상 새 객체를 반환한다는 것입니다.

String s1 = "something";
String s2 = "else";
String s3 = s1 + s2; // this is creating a new object.

4

StringBuilder는 더 큰 문자열을 다룰 때 좋습니다. 성능 향상에 도움이됩니다.

여기 에 도움 이 된 기사 가 있습니다.

빠른 Google 검색이 도움이 될 수 있습니다. 이제 7 명의 다른 사람을 고용하여 Google 검색을 수행했습니다. :)


우리 모두 여기서 무급으로 일하고 있지 않나요?
Deadpool 2019 년

4

정확하게 말하면 StringBuilder는 모든 문자열을 추가하는 것은 O (N)이고 String을 추가하는 것은 O (N ^ 2)입니다. 소스 코드를 확인하면 변경 가능한 문자 배열을 유지하여 내부적으로 수행됩니다. StringBuilder는 배열 길이 복제 기술을 사용하여 잠재적으로 필요한 메모리를 두 배로 늘리는 대신 Ammortized O (N ^ 2) 성능 을 달성 합니다. 이 문제를 해결하기 위해 마지막에 trimToSize를 호출 할 수 있지만 일반적으로 StringBuilder 객체는 일시적으로 만 사용됩니다. 최종 문자열 크기에서 좋은 시작 추측을 제공하여 성능을 더욱 향상시킬 수 있습니다.


3

능률.

문자열을 연결할 때마다 새 문자열이 생성됩니다. 예를 들면 :

String out = "a" + "b" + "c";

이렇게하면 새 임시 문자열이 만들어지고 "a"와 "b"가 복사되어 "ab"가됩니다. 그런 다음 다른 새 임시 문자열을 만들고 "ab"와 "c"를 복사하여 "abc"가됩니다. 이 결과는에 할당됩니다 out.

결과는 O (n²) (2 차) 시간 복잡도에 대한 화가 Schlemiel 알고리즘 입니다.

StringBuilder반면에 문자열을 제자리에 추가하여 필요에 따라 출력 문자열의 크기를 조정할 수 있습니다.


많은 JVM 구현은 예제를 StringBuilder로 컴파일 한 다음 최종 결과를 String으로 변환합니다. 이러한 경우 반복되는 문자열 할당으로 어셈블되지 않습니다.
scottb

1

Java에는 String, StringBuffer 및 StringBuilder가 있습니다.

  • String : 불변

  • StringBuffer : 변경 가능하고 ThreadSafe

  • StringBuilder : 변경 가능하지만 ThreadSafe는 아님, Java 1.5에 도입 됨

문자열 예 :

public class T1 {

    public static void main(String[] args){

        String s = "Hello";

        for (int i=0;i<10;i++) {

            s = s+"a";
            System.out.println(s);
        }
    }
}

}

출력 : 1 개의 문자열 대신 10 개의 다른 문자열이 생성됩니다.

Helloa
Helloaa
Helloaaa
Helloaaaa
Helloaaaaa
Helloaaaaaa
Helloaaaaaaa
Helloaaaaaaaa 
Helloaaaaaaaaa 
Helloaaaaaaaaaa

StringBuilder 예 : StringBuilder 객체는 1 개만 생성됩니다.

public class T1 {

    public static void main(String[] args){

        StringBuilder s = new StringBuilder("Hello");

        for (int i=0;i<10;i++) {    
            s.append("a");
            System.out.println(s);
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.