Programing

String, StringBuffer 및 StringBuilder

lottogame 2020. 5. 6. 20:48
반응형

String, StringBuffer 및 StringBuilder


비교 나에게 실시간으로 상황을 알려주십시오 String, StringBuffer그리고 StringBuilder?


돌연변이 차이 :

String이다 불변 당신이 그 값을 변경하려고하면, 또 다른 목적은 반면, 작성되는, StringBuffer그리고 StringBuilder있습니다 가변 그들의 값을 변경할 수 있습니다.

스레드 안전성 차이 :

의 차이 StringBuffer와는 StringBuilderStringBuffer스레드 안전합니다. 따라서 응용 프로그램을 단일 스레드에서만 실행해야하는 경우 사용하는 것이 좋습니다 StringBuilder. StringBuilder보다 효율적 StringBuffer입니다.

상황 :

  • 문자열이 변경되지 않으면 String객체는 변경할 수 없으므로 String 클래스를 사용하십시오 .
  • 문자열이 변경 될 수 있고 (예 : 문자열 구성시 많은 논리와 연산) 단일 스레드에서만 액세스 할 수 있다면 a를 사용하는 StringBuilder것으로 충분합니다.
  • 문자열이 변경되어 여러 스레드에서 액세스되는 경우 동기식 StringBuffer이기 때문에 StringBuffer스레드 안전을 가지기 때문에를 사용하십시오 .

  • 당신은 사용 String불변의 구조가 적합한 경우; 에서 새로운 문자 시퀀스를 얻는 것은 StringCPU 시간 또는 메모리에서 허용 할 수없는 성능 저하를 가져올 수 있습니다 (데이터가 복사되지 않기 때문에 서브 스트링을 얻는 것이 CPU 효율적이지만, 이는 잠재적으로 훨씬 많은 양의 데이터가 할당 된 상태로 남아있을 수 있음).
  • StringBuilder일반적으로 여러 문자 시퀀스를 연결하기 위해 가변 문자 시퀀스를 만들어야 할 때 사용 합니다.
  • 당신이 사용하는 StringBuffer당신이 사용하는 것과 같은 상황에서 StringBuilder, 그러나 기본 문자열로 변경하는 경우 (여러 개의 스레드가 읽기 때문에 / modifyind 문자열 버퍼)를 동기화해야합니다.

예를 참조 하십시오 .


기본 사항 :

String불변의 클래스이므로 변경할 수 없습니다. StringBuilder, 추가 문자를 교체하거나 제거하고 궁극적으로 변환 할 수있는 가변 클래스는 String StringBuffer원래 동기화 버전StringBuilder

StringBuilder객체에 액세스하는 단일 스레드 만있는 모든 경우를 선호해야 합니다.

세부 사항 :

또한 StringBuilder/Buffers마술이 아니라 배열을 백업 개체로 사용하기 때문에 배열이 가득 차면 배열을 다시 할당해야합니다. 호출 StringBuilder/Buffer될 때마다 지속적으로 크기를 조정할 필요가없는 원래 충분히 큰 객체를 작성하십시오 .append().

크기를 조정하면 성능이 매우 저하 될 수 있습니다. 기본적으로 확장해야 할 때마다 기본 배열의 크기를 현재 크기의 2 배로 조정합니다. 이로 인해 많은 양의 RAM이 할당되고 StringBuilder/Buffer클래스가 커지기 시작할 때 사용되지 않을 수 있습니다.

자바 String x = "A" + "B";에서는 StringBuilder배후를 사용 합니다. 따라서 간단한 경우에는 자신을 선언해도 이점이 없습니다. 그러나 String4k 미만의 큰 객체를 빌드하는 경우 선언하는 StringBuilder sb = StringBuilder(4096);것이 연결 또는 16자인 기본 생성자사용하는 것보다 훨씬 효율적 입니다. 당신이 경우 String적은 10K보다가 될 것입니다 후 안전을 위해 10K에 생성자를 초기화합니다. 그러나 10k로 초기화되면 10k보다 큰 1자를 쓰면 다시 할당되어 20k 배열로 복사됩니다. 따라서 높은 초기화는 낮은 것보다 낫습니다.

자동 크기 조정의 경우, 17 번째 문자에서 백업 배열이 재배치되어 32 자로 복사되고, 33 번째 문자에서 다시 발생하고 배열을 64 문자로 다시 할당하고 복사하게됩니다. 이 방법이 많은 재 할당 및 사본으로 어떻게 퇴보되는지 확인할 수 있습니다 StringBuilder/Buffer.

AbstractStringBuilder의 JDK 6 소스 코드에서 가져온 것입니다.

   void expandCapacity(int minimumCapacity) {
    int newCapacity = (value.length + 1) * 2;
        if (newCapacity < 0) {
            newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
        newCapacity = minimumCapacity;
    }
        value = Arrays.copyOf(value, newCapacity);
    }

가장 좋은 방법은 StringBuilder/Buffer손이 얼마나 큰지 알지 String못하지만 추측 할 수있는 경우 필요한 것보다 조금 크게 초기화하는 입니다. 필요한 것보다 약간 더 많은 메모리를 할당하는 것이 많은 재 할당 및 사본보다 낫습니다.

또한 String + 16 문자의 크기 만 할당 StringBuilder/Buffer하는 Stringas로 a를 초기화하는 것을 조심하십시오 . 대부분의 경우 피할 수있는 퇴화 재 할당 및 복사주기 만 시작합니다. 다음은 Java 6 소스 코드와 동일합니다.

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
    }

우연히 StringBuilder/Buffer생성하지 않았고 호출 된 생성자를 제어 할 수없는 인스턴스가 생길 경우, 재 할당 및 복사 동작의 변형을 피할 수있는 방법이 있습니다. .ensureCapacity()결과 String가 나아지도록 원하는 크기로 전화 하십시오 .

대안 :

참고로, 실제로 무거운 String 건물과 조작을 수행하는 경우 Ropes 라는 훨씬 성능 지향적 인 대안이 있습니다.

또 다른 대안은 StringList서브 클래 싱을 통해 구현 을 생성하고 ArrayList<String>카운터를 추가 .append()하여 목록의 모든 돌연변이 작업에서 문자 수를 추적 한 다음 재정 의하여 필요한 정확한 크기 .toString()를 생성 StringBuilder하고 목록을 반복하여 빌드하는 것입니다. 출력을 StringBuilder통해 인스턴스 변수를 만들고 결과를 '캐시'할 수 있으며 .toString()변경 사항이있을 때만 다시 생성해야합니다.

또한 String.format()고정 형식의 출력을 빌드 할 때 잊지 말고 컴파일러가 더 나은 결과를 얻을 수 있도록 최적화하십시오.


연결을 의미합니까?

실제 예 : 많은 다른 문자열 중에서 새 문자열을 만들려고합니다 .

예를 들어 메시지를 보내려면 :

String s = "Dear " + user.name + "<br>" + 
" I saw your profile and got interested in you.<br>" +
" I'm  " + user.age + "yrs. old too"

StringBuilder

String s = new StringBuilder().append.("Dear ").append( user.name ).append( "<br>" ) 
          .append(" I saw your profile and got interested in you.<br>") 
          .append(" I'm  " ).append( user.age ).append( "yrs. old too")
          .toString()

또는

String s = new StringBuilder(100).appe..... etc. ...
// The difference is a size of 100 will be allocated upfront as  fuzzy lollipop points out.

StringBuffer ( the syntax is exactly as with StringBuilder, the effects differ )

About

StringBuffer vs. StringBuilder

The former is synchonized and later is not.

So, if you invoke it several times in a single thread ( which is 90% of the cases ), StringBuilder will run much faster because it won't stop to see if it owns the thread lock.

So, it is recommendable to use StringBuilder ( unless of course you have more than one thread accessing to it at the same time, which is rare )

String concatenation ( using the + operator ) may be optimized by the compiler to use StringBuilder underneath, so, it not longer something to worry about, in the elder days of Java, this was something that everyone says should be avoided at all cost, because every concatenation created a new String object. Modern compilers don't do this anymore, but still it is a good practice to use StringBuilder instead just in case you use an "old" compiler.

edit

Just for who is curious, this is what the compiler does for this class:

class StringConcatenation {
    int x;
    String literal = "Value is" + x;
    String builder = new StringBuilder().append("Value is").append(x).toString();
}

javap -c StringConcatenation

Compiled from "StringConcatenation.java"
class StringConcatenation extends java.lang.Object{
int x;

java.lang.String literal;

java.lang.String builder;

StringConcatenation();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   new #2; //class java/lang/StringBuilder
   8:   dup
   9:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
   12:  ldc #4; //String Value is
   14:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   17:  aload_0
   18:  getfield    #6; //Field x:I
   21:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   24:  invokevirtual   #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   27:  putfield    #9; //Field literal:Ljava/lang/String;
   30:  aload_0
   31:  new #2; //class java/lang/StringBuilder
   34:  dup
   35:  invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
   38:  ldc #4; //String Value is
   40:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   43:  aload_0
   44:  getfield    #6; //Field x:I
   47:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   50:  invokevirtual   #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   53:  putfield    #10; //Field builder:Ljava/lang/String;
   56:  return

}

Lines numbered 5 - 27 are for the String named "literal"

Lines numbered 31-53 are for the String named "builder"

Ther's no difference, exactly the same code is executed for both strings.


String Family

String

The String class represents character strings. All string literals in Java program, such as "abc" are implemented as instances of this class.

String objects are immutable once they are created we can't change. (Strings are constants)

  • If a String is created using constructor or method then those strings will be stored in Heap Memory as well as SringConstantPool. But before saving in pool it invokes intern() method to check object availability with same content in pool using equals method. If String-copy is available in the Pool then returns the reference. Otherwise, String object is added to the pool and returns the reference.

    • The Java language provides special support for the string concatenation operator (+), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method.

    String heapSCP = new String("Yash");
    heapSCP.concat(".");
    heapSCP = heapSCP + "M";
    heapSCP = heapSCP + 777;
    
    // For Example: String Source Code 
    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }
    
  • String literals are stored in StringConstantPool.

    String onlyPool = "Yash";
    

StringBuilder and StringBuffer are mutable sequence of characters. That means one can change the value of these object's. StringBuffer has the same methods as the StringBuilder, but each method in StringBuffer is synchronized so it is thread safe.

  • StringBuffer and StringBuilder data can only be created using new operator. So, they get stored in Heap memory.

  • Instances of StringBuilder are not safe for use by multiple threads. If such synchronization is required then it is recommended that StringBuffer be used.

    StringBuffer threadSafe = new StringBuffer("Yash");
    threadSafe.append(".M");
    threadSafe.toString();
    
    StringBuilder nonSync = new StringBuilder("Yash");
    nonSync.append(".M");
    nonSync.toString();
    
  • StringBuffer and StringBuilder are having a Special methods like., replace(int start, int end, String str) and reverse().

    NOTE: StringBuffer and SringBuilder are mutable as they provides the implementation of Appendable Interface.


When to use which one.

  • If a you are not going to change the value every time then its better to Use String Class. As part of Generics if you want to Sort Comparable<T> or compare a values then go for String Class.

    //ClassCastException: java.lang.StringBuffer cannot be cast to java.lang.Comparable
    Set<StringBuffer> set = new TreeSet<StringBuffer>();
    set.add( threadSafe );
    System.out.println("Set : "+ set);
    
  • If you are going to modify the value every time the go for StringBuilder which is faster than StringBuffer. If multiple threads are modifying the value the go for StringBuffer.


----------------------------------------------------------------------------------
                  String                    StringBuffer         StringBuilder
----------------------------------------------------------------------------------                 
Storage Area | Constant String Pool         Heap                   Heap 
Modifiable   |  No (immutable)              Yes( mutable )         Yes( mutable )
Thread Safe  |      Yes                     Yes                     No
 Performance |     Fast                 Very slow                  Fast
----------------------------------------------------------------------------------

Also, StringBuffer is thread-safe, which StringBuilder is not.

So in a real-time situation when different threads are accessing it, StringBuilder could have an undeterministic result.


Note that if you are using Java 5 or newer, you should use StringBuilder instead of StringBuffer. From the API documentation:

As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, StringBuilder. The StringBuilder class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization.

In practice, you will almost never use this from multiple threads at the same time, so the synchronization that StringBuffer does is almost always unnecessary overhead.


Personally, I don't think there is any real world use for StringBuffer. When would I ever want to communicate between multiple threads by manipulating a character sequence? That doesn't sound useful at all, but maybe I have yet to see the light :)


Difference between String and the other two classes is that String is immutable and the other two are mutable classes.

But why we have two classes for same purpose?

Reason is that StringBuffer is Thread safe and StringBuilder is not. StringBuilder is a new class on StringBuffer Api and it was introduced in JDK5 and is always recommended if you are working in a Single threaded environment as it is much Faster

For complete Details you can read http://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/


In java, String is immutable. Being immutable we mean that once a String is created, we can not change its value. StringBuffer is mutable. Once a StringBuffer object is created, we just append the content to the value of object instead of creating a new object. StringBuilder is similar to StringBuffer but it is not thread-safe. Methods of StingBuilder are not synchronized but in comparison to other Strings, the Stringbuilder runs fastest. You can learn difference between String, StringBuilder and StringBuffer by implementing them.

참고URL : https://stackoverflow.com/questions/2971315/string-stringbuffer-and-stringbuilder

반응형