What classes do Java have for manipulating strings? What's the difference?

  • 2021-09-16 06:53:30
  • OfStack

What are the classes that manipulate strings? What's the difference?

There are mainly three classes for manipulating strings, which are String, StringBuffer and StringBuilder.

Immutable string

Class String


public class StringTest {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        String s3 = new String("abc");	
        System.out.println(s1 == s2);	// true
        System.out.println(s2 == s3);	// false
        s2 = "abc" + "def";
        System.out.println(s1 == s2);	// false
        String s4 = "abcdef";
        System.out.println(s4 == s2);	// true
    }
}

1. When using = When the String class is initialized, an object is created in the constant pool, pointing the reference s1 to an address in the constant pool.

2. When you create s2, you will first check whether there are any in the constant pool "abc" If any, point s2 directly to the "abc" So s1 and s2 point to the same object.

STEP 3 Use new Keyword to create an String object, it will open up a block of memory in the heap space, and then initialize s3 in the heap, and s3 points to an area in the heap memory space.

4. When we modified s2, we actually added new objects to the constant pool "abcdef" At this point, we will create the new object s4 in the same steps as creating s2. s4 is found in the constant pool "abcdef" So point directly to this object.

When we operate on variables of String type, we actually create new objects every time we change them.

Variable string

The StringBuffer and StringBuilder classes both provide methods for adding and deleting strings. Here is an example of adding new characters to the original object.


public class StringTest2 {
    public static void main(String[] args) {
        StringBuffer sb1 = new StringBuffer("abc");
        StringBuilder sb2 = new StringBuilder("abc");
        System.out.println(sb1.hashCode());	// 460141958
        System.out.println(sb2.hashCode());	// 1163157884
        sb1.append("def");
        sb2.append("def");
        System.out.println(sb1.hashCode()); // 460141958
        System.out.println(sb2.hashCode()); // 1163157884
    }
}

From this example, we can clearly see that s1 and s2 are still the same object before and after adding elements.
StringBuffer and StringBuilder both inherit AbstractStringBuilder Class.

Class StringBuffer

Compared with the StringBuilder class, the methods in the StringBuffer class are not used synchronized Keyword.


   @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

Class StringBuilder


  @Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }

append method of AbstractStringBuilder class

Expansion method: Call ensureCapacityInternal () method to check the initial char[] value Whether the space is enough, if not, the expansion operation will be carried out.


 public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        //  See if there is enough space 
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

 private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        //  If there is not enough space, reopen it 1 Block new space 
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }

copyOf method: Recreate a new char array and copy the original array data to the new array.


    public static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

Summary

There are three classes of Java operating strings, which are String, StringBuffer and StringBuilder char[] Save string objects in the form. The differences between them are mainly reflected in:

1. The modification of String type is equivalent to recreating the object, and the addition and deletion operations of StringBuffer and StringBuilder are aimed at the same object.

2. Most methods in StringBuffer are not modified by synchronized keyword, so the performance is higher (I also write this when brushing questions). StringBuffer class is preferred in single-threaded environment, and StringBuilder class is needed to ensure thread safety in multi-threaded environment.

3. If the string does not need to be changed after the declaration, it is the best choice to declare the String class directly. When the String object is declared without the new keyword, it will not open up space in the heap memory, but directly point to the String constant pool. This can realize reuse and reduce resource consumption.

Extended reading

The difference between method overloading and method rewriting of Java basic series 1 bomb
Characteristics of Java polymorphic member access in the second bomb of Java basic series


Related articles: