문제

Java의 String과 StringBuffer의 차이점은 무엇입니까?

문자열의 최대 크기가 있습니까?

도움이 되었습니까?

해결책

String 변경할 수없는 문자열을 조작하는 데 사용됩니다 (읽기 전용 및 불변).

StringBuffer 수정할 수있는 문자를 나타내는 데 사용됩니다.

성능 현명한, StringBuffer 연결을 수행 할 때 더 빠릅니다. 이것은 당신이 연결할 때 a String, 당신은 이후 매번 (내부적으로) 새 개체를 만들고 있습니다. String 불변입니다.

당신은 또한 사용할 수 있습니다 StringBuilder 비슷합니다 StringBuffer 동기화되지 않은 경우를 제외하고. 이 중 하나의 최대 크기는입니다 Integer.MAX_VALUE (231 -1 = 2,147,483,647) 또는 최대 힙 크기는 2로 나뉩니다 (참조 Java String은 몇 개의 문자를 가질 수 있습니까?). 추가 정보 여기.

다른 팁

String 불변, 즉 만들어 졌을 때 결코 변할 수 없습니다.

StringBuffer (또는 동기화되지 않은 사촌 StringBuilder) 작은 구조의 성능 오버 헤드없이 문자열을 조각별로 만들어야 할 때 사용됩니다. String길을 따라 s.

두 가지의 최대 길이는 정수입니다 .max_value는 내부적으로 배열로 저장되고 Java 어레이는 int 그들의 길이가 유사비.

성능 향상 String모래 StringBuffer다중 연결의 경우 S는 상당히 중요합니다. 다음 테스트 코드를 실행하면 차이가 표시됩니다. Java 6이있는 고대 노트북에서는 다음과 같은 결과를 얻습니다.

Concat with String took: 1781ms
Concat with StringBuffer took: 0ms
public class Concat
{
    public static String concatWithString()
    {
        String t = "Cat";
        for (int i=0; i<10000; i++)
        {
            t = t + "Dog";
        }
        return t;
    }
    public static String concatWithStringBuffer()
    {
        StringBuffer sb = new StringBuffer("Cat");
        for (int i=0; i<10000; i++)
        {
            sb.append("Dog");
        }
        return sb.toString();
    }
    public static void main(String[] args)
    {
        long start = System.currentTimeMillis();
        concatWithString();
        System.out.println("Concat with String took: " + (System.currentTimeMillis() - start) + "ms");
        start = System.currentTimeMillis();
        concatWithStringBuffer();
        System.out.println("Concat with StringBuffer took: " + (System.currentTimeMillis() - start) + "ms");
    }
}
String                                          StringBuffer

Immutable                                       Mutable
String s=new String("karthik");                StringBuffer sb=new StringBuffer("karthik")
s.concat("reddy");                             sb.append("reddy");
System.out.println(s);                         System.out.println(sb);
O/P:karthik                                    O/P:karthikreddy

--->once we created a String object            ---->once we created a StringBuffer object
we can't perform any changes in the existing  we can perform any changes in the existing
object.If we are trying to perform any        object.It is nothing but mutablity of 
changes with those changes a new object       of a StrongBuffer object
will be created.It is nothing but Immutability
of a String object

Use String--->If you require immutabilty
Use StringBuffer---->If you require mutable + threadsafety
Use StringBuilder--->If you require mutable + with out threadsafety

String s=new String("karthik");
--->here 2 objects will be created one is heap and the other is in stringconstantpool(scp) and s is always pointing to heap object

String s="karthik"; 
--->In this case only one object will be created in scp and s is always pointing to that object only

문자열은 불변의 클래스입니다. 이것은 일단 당신이 다음과 같은 문자열의 인스턴스를 인스턴스화한다는 것을 의미합니다.

String str1 = "hello";

메모리의 객체를 변경할 수 없습니다. 대신 새 인스턴스를 생성하고 이전 문자열을 복사 하고이 예에서와 같이 다른 것을 추가해야합니다.

String str1 = "hello";
str1 = str1 + " world!";

실제로 듣고있는 것은 기존 STR1 객체를 업데이트하지 않는다는 것입니다. 우리는 "hello"데이터를 복사하고 "세계"를 복사하면서 새로운 메모리를 모두 재 할당하고 있습니다! 결국,이 새로운 메모리를 가리 키도록 str1 참조를 설정합니다. 그래서 그것은 정말로 이렇게 보입니다.

String str1 = "hello";
String str2 = str1 + " world!";
str1 = str2;

따라서이 "복사 + 붙여 넣기 및 메모리에서 물건을 이동"프로세스는 반복적으로 재귀 적으로 완료되면 매우 비쌀 수 있습니다.

당신이 그런 상황에있을 때, StringBuilder를 계속해서 사용해야합니다. 그것은 변이 가능하며 현장의 끝까지 문자열을 추가 할 수 있습니다. [실제 데이터 구조 인 경우 100%가 아님) 목록이 될 수 있기 때문입니다.

로부터 API :

스레드 안전, 변이 가능한 문자 순서. 문자열 버퍼는 문자열과 같지만 수정할 수 있습니다. 언제든지 특정 문자 순서가 포함되어 있지만 시퀀스의 길이와 내용은 특정 메소드 호출을 통해 변경 될 수 있습니다.

StringBuffer는 많은 문자열에서 단일 문자열을 만드는 데 사용됩니다. 예를 들어 루프에서 문자열의 일부를 추가하려면.

StringBuilder가 동기화되지 않아 빠르지 않기 때문에 StringBuffer에 단일 스레드 만 액세스하는 경우 StringBuffer 대신 StringBuilder를 사용해야합니다.

afaik Java에서 언어로 문자열 크기의 상한은 없지만 JVM은 아마도 상한이있을 것입니다.

Reggie Hutcherso의 비교 성능 문자열 대 StringBuffer에 대한 관심 답변을 찾았습니다.원천: http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html

Java는 StringBuffer 및 String 클래스를 제공하며 String 클래스는 변경할 수없는 문자열을 조작하는 데 사용됩니다. 간단히 말하면, 유형 문자열의 객체는 읽고 불변입니다. StringBuffer 클래스는 수정할 수있는 문자를 나타내는 데 사용됩니다.

이 두 클래스의 중요한 성능 차이점은 간단한 연결을 수행 할 때 StringBuffer가 String보다 빠르다는 것입니다. 문자열 조작 코드에서 문자열이 일상적으로 연결됩니다. 문자열 클래스를 사용하여 연결은 일반적으로 다음과 같이 수행됩니다.

 String str = new String ("Stanford  ");
 str += "Lost!!";

StringBuffer를 사용하여 동일한 연결을 수행하려면 다음과 같은 코드가 필요합니다.

 StringBuffer str = new StringBuffer ("Stanford ");
 str.append("Lost!!");

개발자는 일반적으로 위의 첫 번째 예제가 연결을 위해 첨부 방법을 사용하는 두 번째 예제가 + 연산자를 사용하여 두 개의 문자열 객체를 연결하는 첫 번째 예보다 비용이 많이 든다고 생각하기 때문에 위의 첫 번째 예제가 더 효율적이라고 가정합니다.

+ 연산자는 결백하게 보이지만 생성 된 코드는 놀라운 일을 생성합니다. 연결을 위해 StringBuffer를 사용하면 실제로 문자열을 사용하는 것보다 훨씬 빠른 코드를 생성 할 수 있습니다. 이것이 왜 그런지 알기 위해서는 두 예제에서 생성 된 바이트 코드를 검사해야합니다. String을 사용하는 예제의 바이트 코드는 다음과 같습니다.

0 new #7 <Class java.lang.String>
3 dup 
4 ldc #2 <String "Stanford ">
6 invokespecial #12 <Method java.lang.String(java.lang.String)>
9 astore_1
10 new #8 <Class java.lang.StringBuffer>
13 dup
14 aload_1
15 invokestatic #23 <Method java.lang.String valueOf(java.lang.Object)>
18 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
21 ldc #1 <String "Lost!!">
23 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
26 invokevirtual #22 <Method java.lang.String toString()>
29 astore_1

위치 0에서 9 위치의 바이트 코드는 첫 번째 코드 라인에 대해 실행됩니다.

 String str = new String("Stanford ");

그런 다음 위치 10에서 29 위치의 바이트 코드가 연결을 위해 실행됩니다.

 str += "Lost!!";

상황이 흥미로워집니다. 연결을 위해 생성 된 바이트 코드는 StringBuffer 객체를 생성 한 다음 Append 메소드를 호출합니다. 임시 StringBuffer 객체는 위치 10에서 생성되며 Append 메소드는 위치 23에서 호출됩니다. 문자열 클래스는 불변이기 때문에 StringBuffer를 사용해야합니다. 연쇄.

StringBuffer 객체에서 연결을 수행 한 후에는 문자열로 다시 변환해야합니다. 이것은 위치 26에서 Tostring 메소드로 호출하여 수행됩니다.이 방법은 임시 StringBuffer 객체에서 새 문자열 객체를 만듭니다. 이 임시 StringBuffer 객체의 생성과 그 이후의 스트링 객체로 다시 변환하는 것은 매우 비쌉니다.

요약하면, 위의 두 줄의 코드는 세 가지 개체를 생성합니다.

  1. 위치 0의 문자열 객체
  2. 위치 10의 StringBuffer 객체
  3. 위치 26의 문자열 객체

이제 StringBuffer를 사용하여 예제에 대해 생성 된 바이트 코드를 살펴 보겠습니다.

0 new #8 <Class java.lang.StringBuffer>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
9 astore_1
10 aload_1 
11 ldc #1 <String "Lost!!">
13 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
16 pop

위치 0 ~ 9의 바이트 코드는 첫 번째 코드 라인에 대해 실행됩니다.

 StringBuffer str = new StringBuffer("Stanford ");

위치 10 내지 16의 바이트 코드는 다음과 같은 연합을 위해 실행됩니다.

 str.append("Lost!!");

첫 번째 예에서와 같이이 코드는 StringBuffer 객체의 Append 메소드를 호출합니다. 그러나 첫 번째 예제와 달리 임시 StringBuffer를 만들어 문자열 객체로 변환 할 필요가 없습니다. 이 코드는 위치 0에서 하나의 객체 인 StringBuffer 만 생성합니다.

결론적으로, StringBuffer 연결은 문자열 연결보다 훨씬 빠릅니다. 분명히, StringBuffers는 가능한 경우 이러한 유형의 작업에 사용해야합니다. 문자열 클래스의 기능이 원하는 경우, 연결을 위해 StringBuffer를 사용한 다음 String으로 하나의 변환을 수행하는 것을 고려하십시오.

첨부 작업이 증명 된 후 String/StringBuffer 객체의 해시 코드를 인쇄함으로써 String Object는 동일한 문자열 객체를 사용하지 않고 새 값으로 매번 내부적으로 재현됩니다.

public class MutableImmutable {

/**
 * @param args
 */
public static void main(String[] args) {
    System.out.println("String is immutable");
    String s = "test";
    System.out.println(s+"::"+s.hashCode());
    for (int i = 0; i < 10; i++) {
        s += "tre";
        System.out.println(s+"::"+s.hashCode());
    }

    System.out.println("String Buffer is mutable");

    StringBuffer strBuf = new StringBuffer("test");
    System.out.println(strBuf+"::"+strBuf.hashCode());
    for (int i = 0; i < 10; i++) {
        strBuf.append("tre");
        System.out.println(strBuf+"::"+strBuf.hashCode());
    }

 }

}

출력 : 해시 코드와 함께 객체 값을 인쇄합니다.

    String is immutable
    test::3556498
    testtre::-1422435371
    testtretre::-1624680014
    testtretretre::-855723339
    testtretretretre::2071992018
    testtretretretretre::-555654763
    testtretretretretretre::-706970638
    testtretretretretretretre::1157458037
    testtretretretretretretretre::1835043090
    testtretretretretretretretretre::1425065813
    testtretretretretretretretretretre::-1615970766
    String Buffer is mutable
    test::28117098
    testtre::28117098
    testtretre::28117098
    testtretretre::28117098
    testtretretretre::28117098
    testtretretretretre::28117098
    testtretretretretretre::28117098
    testtretretretretretretre::28117098
    testtretretretretretretretre::28117098
    testtretretretretretretretretre::28117098
    testtretretretretretretretretretre::28117098

StringBuffer 또는 더 젊고 빠른 형제 StringBuilder 당신이 맛의 많은 문자열 연결을 할 때마다 선호됩니다.

string += newString;

또는 동등하게

string = string + newString;

위의 구성이 암시 적으로 생성되기 때문입니다 새로운 매번 문자열은 큰 성능과 드롭이 될 것입니다. ㅏ StringBuffer / StringBuilder 동적으로 확장 가능한 것과 비교하는 것이 가장 좋은 후드 아래에 있습니다. List<Character>.

String 불변의 캐릭터 배열입니다.

StringBuffer 변한 캐릭터 배열입니다. 종종 다시 변환되었습니다 String 돌연변이가 완료되면.

둘 다 배열이므로 두 가지의 최대 크기는 정수의 최대 크기와 같으며 2^31-1입니다 ( Javadoc, 또한 Javadoc을 모두 확인하십시오 String 그리고 StringBuffer). 이것은 때문입니다 .length 배열의 인수는 원시입니다 int. (보다 배열).

문자열은 불변이기 때문에 문자열에서 작업을 수행 할 때 완전히 새 문자열을 생성한다는 의미입니다.

StringBuffer 변이 가능하며, 길이를 0으로 재설정 할뿐만 아니라 추가 할 수 있습니다.

실제로, 컴파일러는 문자열 연결 중에 StringBuffer를 사용하는 것 같습니다. 성능 이유로.

String is immutable. 

왜요? 확인하다 여기.

StringBuffer is not. It is thread safe. 

다음과 같은 다른 개념을 사용할 수있는시기와 같은 추가 질문 이것.

도움이 되었기를 바랍니다.

나는 이것이 주요 차별화 요소가 아니라는 것을 이해하지만 오늘날 StringBuffer (및 StringBuilder)는 String이 그렇지 않은 흥미로운 방법을 제공한다는 것을 알았습니다.

  • 뒤집다()
  • setcharat ()

차이점이 있습니다

  1. 수업 + 연산자가 과부하되었습니다. 우리는 두 개의 문자열 객체를 사용하여 연결할 수 있습니다 + 운영자이지만 경우 StringBuffer 우리는 할 수 없습니다.
  2. 클래스는 toString (), equals (), hashcode ()를 우선시합니다. 물체 수업, 그러나 StringBuffer toString () 만 무시합니다.

    String s1 = new String("abc");
    String s2 = new String("abc");
    System.out.println(s1.equals(s2));  // output true
    
    StringBuffer sb1 = new StringBuffer("abc");
    StringBuffer sb2 = new StringBuffer("abc");
    System.out.println(sb1.equals(sb2));  // output false
    
  3. 수업은 둘 다입니다 직렬화 가능 만큼 잘 유사한, 하지만 StringBuffer 오직 직렬화 가능.

    Set<StringBuffer> set = new TreeSet<StringBuffer>();
    set.add(sb1);
    set.add(sb2);
    System.out.println(set);  // gives ClassCastException because there is no Comparison mechanism
    
  4. 우리는 또는없이 문자열 객체를 만들 수 있습니다 새로운 연산자이지만 StringBuffer 객체는 새로운 운영자.

  5. 문자열은 불변이지만 StringBuffer는 변동성이 있습니다.
  6. StringBuffer는 동기화되지만 String은 그렇지 않습니다.
  7. StringBuffer는 제작되었습니다 뒤집다() 방법이지만 문자열은 그것을 가지고 있지 않습니다.

성능 현명한 StringBuffer는 문자열보다 훨씬 낫습니다. 문자열 객체에 연결을 적용 할 때마다 각 연결에 새 문자열 객체가 생성됩니다.

주요 규칙 : 문자열은 불변 (수정할 수 없음)이고 StringBuffer는 Mutable (수정 가능)입니다.

성능 차이를 얻는 프로그램 실험은 다음과 같습니다.

public class Test {

  public static int LOOP_ITERATION= 100000;

  public static void stringTest(){
    long startTime = System.currentTimeMillis();
    String string = "This";
    for(int i=0;i<LOOP_ITERATION;i++){
        string = string+"Yasir";
    }

    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);    
  }

  public static void stringBufferTest(){
    long startTime = System.currentTimeMillis();
    StringBuffer stringBuffer = new StringBuffer("This");
    for(int i=0;i<LOOP_ITERATION;i++){
        stringBuffer.append("Yasir");
    }

    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);
  }

  public static void main(String []args){
    stringTest()
    stringBufferTest(); 
  }
 }

문자열 출력이 내 컴퓨터에 있습니다 14800

StringBuffer의 출력이 내 컴퓨터에 있습니다 14

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top