program tip

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

radiobox 2020. 11. 23. 07:58
반응형

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


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

String의 최대 크기가 있습니까?


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

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

성능면에서 StringBuffer연결을 수행 할 때 더 빠릅니다. 를 연결할 때는 변경 불가능 String하므로 매번 새 객체 (내부적으로)를 생성하기 때문 String입니다.

동기화되지 않는다는 점 StringBuilderStringBuffer제외하고 유사한 것을 사용할 수도 있습니다 . 이들 중 하나의 최대 크기는 Integer.MAX_VALUE(2 31-1 = 2,147,483,647) 또는 최대 힙 크기를 2로 나눈 값입니다 ( Java 문자열에 사용할 수있는 문자 수 참조 ). 자세한 정보는 여기 .


A String는 변경 불가능합니다. 즉, 생성 될 때 변경 될 수 없습니다.

A StringBuffer(또는 동기화되지 않은 사촌 StringBuilder)는 String도중에 많은 작은 s 를 생성하는 성능 오버 헤드없이 문자열을 하나씩 구성해야 할 때 사용됩니다 .

둘 다의 최대 길이는 Integer.MAX_VALUE입니다. 내부적으로 배열로 저장되기 때문이며 Java 배열에는 int길이 의사 필드 만 있습니다.

다중 연결에 대한 Strings와 StringBuffers 간의 성능 향상 은 상당히 중요합니다. 다음 테스트 코드를 실행하면 차이점을 알 수 있습니다. Java 6이 설치된 오래된 랩톱에서 다음과 같은 결과를 얻었습니다.

문자열을 사용한 연결 소요 시간 : 1781ms
StringBuffer를 사용한 Concat 소요 시간 : 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"데이터를 복사하고 "world!"를 추가합니다. 끝까지 str1 참조가이 새 메모리를 가리 키도록 설정합니다. 따라서 실제로는 다음과 같이 보입니다.

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

따라서이 "복사 + 붙여 넣기 및 메모리에서 항목 이동"프로세스는 반복적으로 특히 재귀 적으로 수행되는 경우 매우 비쌀 수 있습니다.

일을 반복해야하는 상황에서 StringBuilder를 활용하십시오. 그것은 가변적이며 [성장하는 배열] (실제 데이터 구조 인 경우 100 %가 아니라 목록 일 수 있음)에 의해 돌아 오기 때문에 현재 문자열의 끝에 문자열을 추가 할 수 있습니다.


로부터 API :

스레드로부터 안전하고 변경 가능한 문자 시퀀스입니다. 문자열 버퍼는 문자열과 비슷하지만 수정할 수 있습니다. 어느 시점에서든 특정 문자 시퀀스가 ​​포함되어 있지만 시퀀스의 길이와 내용은 특정 메서드 호출을 통해 변경할 수 있습니다.


StringBuffer는 여러 문자열에서 단일 문자열을 만드는 데 사용됩니다 (예 : 루프에서 문자열의 일부를 추가하려는 경우).

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

AFAIK는 Java에서 언어로서의 문자열 크기에 대한 상한이 없지만 JVM에는 아마도 상한이 있습니다.


Reggie Hutcherso의 성능 비교 String vs StringBuffer에 대한 관심 답변을 찾았습니다 . 출처 : http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html

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

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

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

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

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

개발자는 일반적으로 위의 첫 번째 예제가 더 효율적이라고 가정합니다. 연결을 위해 append 메서드를 사용하는 두 번째 예제가 + 연산자를 사용하여 두 String 개체를 연결하는 첫 번째 예제보다 비용이 더 많이 든다고 생각하기 때문입니다.

+ 연산자는 무해한 것처럼 보이지만 생성 된 코드는 놀라운 결과를 낳습니다. 연결에 StringBuffer를 사용하면 실제로 String을 사용하는 것보다 훨씬 빠른 코드를 생성 할 수 있습니다. 이것이 왜 그런지 알아 보려면 두 예제에서 생성 된 바이트 코드를 조사해야합니다. 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에서 호출됩니다. String 클래스는 변경 불가능하므로 StringBuffer를 사용해야합니다. 연쇄.

연결이 StringBuffer 개체에서 수행 된 후 다시 문자열로 변환되어야합니다. 이는 26 번 위치에서 toString 메소드를 호출하여 수행됩니다.이 메소드는 임시 StringBuffer 객체에서 새로운 String 객체를 생성합니다. 이 임시 StringBuffer 객체를 생성하고 이후에 String 객체로 다시 변환하는 데는 비용이 많이 듭니다.

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

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

이제 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를 만든 다음 String 개체로 변환 할 필요가 없습니다. 이 코드는 위치 0에 하나의 객체 인 StringBuffer 만 만듭니다.

결론적으로 StringBuffer 연결은 String 연결보다 훨씬 빠릅니다. 분명히 StringBuffers는 가능한 경우 이러한 유형의 작업에 사용되어야합니다. String 클래스의 기능이 필요한 경우 연결에 StringBuffer를 사용한 다음 String으로 한 번의 변환을 수행하는 것이 좋습니다.


추가 작업도 증명 한 후 String / StringBuffer 개체의 해시 코드를 인쇄하면 String 개체가 동일한 String 개체를 사용하지 않고 매번 새로운 값으로 내부적으로 다시 생성됩니다.

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

A StringBuffer또는 더 젊고 빠른 형제 StringBuilder는 풍미에서 많은 문자열 연결을 할 때마다 선호됩니다.

string += newString;

또는 동등하게

string = string + newString;

위의 구성은 매번 새로운 문자열을 암시 적으로 생성하기 때문에 엄청난 성능과 저하가 ​​발생합니다. A StringBuffer/ StringBuilder는 동적으로 확장 가능한 것과 비교하는 것이 가장 좋습니다 List<Character>.


A String는 변경 불가능한 문자 배열입니다.

A StringBuffer는 가변 문자 배열입니다. 종종 String돌연변이가 완료되면 다시 변환됩니다 .

Since both are an array, the maximum size for both is equal to the maximum size of an integer, which is 2^31-1 (see JavaDoc, also check out the JavaDoc for both String and StringBuffer).This is because the .length argument of an array is a primitive int. (See Arrays).


String is immutable, meaning that when you perform an operation on a String you are really creating a whole new String.

StringBuffer is mutable, and you can append to it as well as reset its length to 0.

In practice, the compiler seems to use StringBuffer during String concatenation for performance reasons.


String is immutable. 

Why? Check here.

StringBuffer is not. It is thread safe. 

Further questions like when to use which and other concepts can be figured out following this.

Hope this helps.


While I understand that this is not a major differentiating factor, I noticed today that StringBuffer(and StringBuilder) provides some interesting methods that String doesn't.

  • reverse()
  • setCharAt()

The differences are

  1. Only in String class + operator is overloaded. We can concat two String object using + operator, but in the case of StringBuffer we can't.
  2. String class is overriding toString(), equals(), hashCode() of Object class, but StringBuffer only overrides 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. String class is both Serializable as well as Comparable, but StringBuffer is only Serializable.

    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. We can create a String object with and without new operator, but StringBuffer object can only be created using new operator.

  5. String is immutable but StringBuffer is mutable.
  6. StringBuffer is synchronized, whereas String ain't.
  7. StringBuffer is having an in-built reverse() method, but String dosen't have it.

Performance wise StringBuffer is much better than String ; because whenever you apply concatenation on String Object then new String object are created on each concatenation.

Principal Rule : String are immutable(Non Modifiable) and StringBuffer are mutable(Modifiable)

Here is the programmatic experiment where you get the performance difference

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(); 
  }
 }

Output of String are in my machine 14800

Output of StringBuffer are in my machine 14

참고URL : https://stackoverflow.com/questions/2439243/what-is-the-difference-between-string-and-stringbuffer-in-java

반응형