What is the difference between String, StringBuffer and StringBuilder of Java foundation?

What is the difference between String, StringBuffer and StringBuilder of Java foundation?

1.String

1.1 String memory storage

Storage method: use char array inside the string to save the contents of the string. Each bit in the data stores a character. The length of char array is also the length of the string. For example, the storage method of "hello world" is:

In the source code, it is expressed as:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];//Because of the "final" modifier, you can know that the string object is immutable.
    /** Cache the hash code for the string */
    private int hash; // Default to 0
}

Description of String memory location: explicit (String that can be determined during compilation) is stored in the String constant pool, while the String object from new is stored in the heap, and the reference of String object is stored in the stack, that is, if the new keyword is used or the value is uncertain during compilation, the String pool will not be used.
Tax note: in jdk1 Before 7, the string constant pool was in the method area, in jdk1 After 7, the string constant pool was moved to the heap.
(1) Explicit String constant

    String s1="hello";
	String s3="hello";
    System.out.println(s1==s3);//true

Note: after the first sentence of code is executed, a String object with the value of Hello is created in the constant pool, and the memory address is assigned to s1; When the second sentence is executed, because there is hello in the constant pool, no new String object will be created, and the memory address of s1 will be directly returned to s3. At this time, the references s1 and s3 of the String are in the virtual machine stack, but "hello" is in the constant pool, so the result of their comparison with "= =" is true.

(2) String object

    String s2=new String("hello");
	String s4=new String("hello");
    System.out.println(s2==s4);//false

Note: when Class is loaded, a String object with the value of Hello is created in the constant pool. When the first sentence is executed, a new String("hello") object will be created in the heap, because the object created through the new method is directly allocated space in the heap memory to create the String; When the second sentence is executed, because there is hello in the constant pool, no new String object will be created, and a new String("hello") object will be directly created in the heap; Therefore, when comparing s2 and s4 with "= =", the address in the heap is compared by default, so false is returned.

Note: when comparing two strings, use equals to compare the contents of strings (the same is true for other reference types).

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        //instanceof is a binary operator in Java, with objects on the left and classes on the right; When the object is the object created by the right class or subclass, return true; Otherwise, false is returned.
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

1.2 common methods in string class

Return typeMethod nameeffect
intlength()Gets the length of the string
charcharAt(int i)Returns the char value at the specified index, that is, to get a character in the string
intindexOf(String s)Returns the first occurrence of the incoming string / character in the original string. If it is not found, it returns - 1
intindexOf(String s´╝îint from index)Returns the index at the first occurrence of the specified character in this string / character, starting with the specified index
intlastIndexOf(String s)Returns the position of the last occurrence of the incoming string in the original string. If it is not found, it returns - 1
booleanstartWith(String s)Determines whether the string starts with the incoming string
booleanendWith(String s)Determines whether the string is the end of the incoming string
StringtoLowerCase()Convert string to lowercase string
StringtoUpperCase()Convert string to uppercase string
StringsubString(int start)Intercept the string from the incoming position to the end
StringsubString(int start,int end)Intercept the string, starting from the position of the passed in parameter 1 and ending at the position of parameter 2.
Stringtrim()Remove the spaces on both sides of the string (the one in the middle cannot be removed)
String[]split(String s)Divide the source string into string arrays according to the passed in parameters
stringreplace(new char,old char)Returns a new string obtained by replacing all old char s appearing in this string with new char

2.StringBuffer

String class is a constant class. If you want to create a string object with variable content, you can't use string class, so java provides a StringBuffer class.

public final class StringBuffer extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{/**
     * A cache of the last value returned by toString. Cleared
     * whenever the StringBuffer is modified.
     */
    private transient char[] toStringCache;
    }

The StringBuffer class is a string with variable length. It includes three methods to manipulate strings:
(1) Build string: you can use the append method to add a string to the end, or use the insert method to insert a string into the string. At the same time, we can also set an initial string when creating a StringBuffer object. For example: StringBuffer sbu=new StringBuffer("hello");
(2) Get string: you can use subString to get part of the current string, or you can use toString method to get all strings.
(3) Modify string: you can use the replace method to replace some contents in the string, or use the delete method to delete some characters in the string.
Tax note: you can check the java API for specific methods

public String(StringBuffer buffer) {
        synchronized(buffer) {//StringBuffer is thread safe
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
}

3.StringBuilder

StringBulider is from jdk1 Added after 5, this class uses the same way as StringBuffer, but the difference is that most methods in StringBuffer class are thread safe, while StringBuffer is not thread safe.
Note: for these two operation strings, you can decide which one to use, but it is safer to use StringBuffer when processing multithreading.

public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
}

4. Comparison of string / StringBuffer / StringBuilder

(1) Variable and immutable
The string class uses a character array to save strings. Because there is a "final" modifier, the string object is immutable.
Both StringBuilder and StringBuffer inherit from AbstractStringBuilder class. In AbstractStringBuilder, character arrays are also used to save strings, but both objects are mutable.
(2) Multithreading security
It can be understood as a constant in a thread, which is obviously not safe.
AbstractStringBuilder is the public parent class of StringBuilder and StringBuffer. It defines some basic string operations, such as expandCapacity, append, insert, indexOf and other public methods.
StringBuffer adds a synchronization lock to the method or adds a synchronization lock to the called method, so it is thread safe.
StringBuilder does not apply synchronization lock to methods, so it is non thread safe.
(3) What StringBuilder and StringBuffer have in common
StringBuilder and StringBuffer have a common parent class abstractstringbuilder (abstract class).
One of the differences between abstract classes and interfaces is that some public methods of subclasses can be defined in abstract classes. Subclasses only need to add new functions and do not need to write existing methods repeatedly; The interface is only the declaration of methods and the definition of constants.
(4) String connection
When connecting a large number of strings, StringBuffer or StringBuffer is generally used, because it provides a buffer function. It will not operate the memory frequently during string splicing, but it will operate the memory frequently when using plus sign for string splicing, which will reduce the performance of the program.
For example:

public class Test{
	/**
	 * StringBuffer:A String buffer similar to String, which is thread safe and heavyweight. The operation efficiency of String splicing is higher than that of String
	 * StringBulider:JDK1.5 After that, non thread safe and lightweight
	 * Efficiency of massive string splicing: StringBuffer > StringBuffer > string
	 * Suggestion: if you want to splice a large number of strings, you should use StringBuilder
	 */
	public static void main(String[] args) {
		Season sea=Season.SPRING;
		Season1 sea1=Season1.SPRING;
		//Season sea=new Season("spring");
		String s="";
		long start=System.currentTimeMillis();
		for(int i=0;i<100000;i++){
			s=s+i;
		}
		long end=System.currentTimeMillis();
		
		//System.out.println(s);
		//System.out.println("String used for" + (end start));
		StringBuffer sbu=new StringBuffer();
		long start1=System.currentTimeMillis();
		for(int i=0;i<100000;i++){
			//s=s+i;
			sbu.append(i);//Method for splicing strings
		}
		long end1=System.currentTimeMillis();

		//System.out.println(sbu.toString());
		System.out.println("StringBuffer Used for"+(end1-start1));
		StringBuilder sbu1=new StringBuilder();
		long start2=System.currentTimeMillis();
		for(int i=0;i<100000;i++){
			//s=s+i;
			sbu1.append(i);//Method for splicing strings
		}
		long end2=System.currentTimeMillis();

		//System.out.println(sbu.toString());
		System.out.println("StringBuilder Used for"+(end2-start2));
	
	}
}

Operation results:

From the above operation results, it can be seen that:
Efficiency of massive string splicing: StringBuffer > StringBuffer > string

Keywords: Java string

Added by harman on Sat, 19 Feb 2022 16:41:54 +0200