J2SE Introduction String, String Buffer, String Builder

Introduction to J2SE (III) String, String Buffer, String Builder

String can be said to be the most frequently used class in Java, and also the knowledge points that are often asked in interviews.

I. Use of String

1. String's immutability

/**
 * The {@code String} class represents character strings. All
 * string literals in Java programs, such as {@code "abc"}, are
 * implemented as instances of this class.
 * <p>
 * Strings are constant; their values cannot be changed after they
 * are created. String buffers support mutable strings.
 * Because String objects are immutable they can be shared. For example:
 * ...
 */

public final class String { 
    private final char value[];
}

Once String objects are created in the heap, they cannot be modified. Because String objects are placed in char arrays, which are modified by final keywords and are immutable.

2. Define a string

/**
 * Define a string
 */
String str1 = "helloworld";

//Yes, but not at all.
String str2 = new String("helloworld");

How does the above code reflect in memory?

3. Assign a defined string again

str1 = "helloChina";

We've already said that String is modified by final keywords and is immutable, so how can it be reflected in memory at this time?

4. Use variables to assign variables

String str3 = str1;

At this point str3 and str1 refer to the same object "hello China"

5. String's handling of "+"

String str4 = "good good" + " study";

By compiling tools

String str4 = "good good study";

So we can find that the compiler merges variables during compilation, instead of creating three objects "good", "study" and "good good study" in memory. But if:

String str5 = str3 + "good good study";

In this case, it is impossible to merge variables during compilation.

6. Common String methods

//str1 == "hello,world ";

//Get Length
str1.length()//12;

//Intercept strings between positions 2 and 5 (including position 2, excluding position 5, starting from 0)
str1.substring(2,5);//"llo"

//Determine whether there is a string "ello"
str1.contains("ello");//true, through indexOf

//Get the start of ello in str1
str1.indexOf("ello");//1

//Converting strings to string data
str1.split(",");//["hello","world"]

//Remove whitespace on both sides of the string
str1.trim();//"hello,world"

II. StringBuffer and StringBuilder

StringBuilder and StringBuffer work to handle strings, but String classes themselves have many ways to handle strings, so why introduce these two classes? Look at the following examples

public static void main(String[] args) {
    String str0 = "hel,lo,wor,l,d";

    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++){
        str0 += i;
    }
    System.out.println(System.currentTimeMillis() - start);

    StringBuilder sb = new StringBuilder("hel,lo,wor,l,d");
    long start1 = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++){
        sb.append(i);
    }
    System.out.println(System.currentTimeMillis() - start1);

    StringBuffer sbf = new StringBuffer("hel,lo,wor,l,d");
    long start2 = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++){
        sbf.append(i);
    }
    System.out.println(System.currentTimeMillis() - start2);
}

Three loops in the above code complete the same function, string splicing, and the results are as follows:

36823
3
4

It can be seen that the execution time is too different. String Buffer and String Builder are introduced in order to solve the business scenario that String is not good at concatenating a large number of strings.

String StringBuffer StringBuilder
final modification, not inheritance final modification, not inheritance final modification, not inheritance
String constants, immutable after creation String variables that can be dynamically modified String variables that can be dynamically modified
There is no thread security problem Thread-safe, all public methods modified by synchronized Thread insecurity
Large numbers of strings are mosaic inefficient A large number of string splicing is very efficient. Large number of strings mosaic efficiency is the highest

StringBuffer is very similar to StringBuilder implementations. Here's a brief description of the basic principles of the append() method with StringBuilder

1. First create a StringBuilder

StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder(100);

StringBuilder operates on strings by char []. StringBuilder created by default constructor has a default length of 16. Of course, the overloaded constructor can be called to pass the initial length. (This is recommended because it can reduce the number of array expansion and improve efficiency.)

/**
 * Constructs a string builder with no characters in it and an
 * initial capacity of 16 characters.
 */
public StringBuilder() {
    super(16);
}

2. StringBuilder's append() method

Each time the append(str) method is called, it is first determined whether the array length is sufficient to add the passed string.

/**
 * Appends the specified string to this character sequence.
 * <p>
 * The characters of the {@code String} argument are appended, in
 * order, increasing the length of this sequence by the length of the
 * argument. If {@code str} is {@code null}, then the four
 * characters {@code "null"} are appended.
 *
 * @param   str   a string.
 * @return  a reference to this object.
 */
public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}
/**
 * For positive values of {@code minimumCapacity}, this method
 * behaves like {@code ensureCapacity}, however it is never
 * synchronized.
 * If {@code minimumCapacity} is non positive due to numeric
 * overflow, this method throws {@code OutOfMemoryError}.
 */
private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    if (minimumCapacity - value.length > 0) {
        value = Arrays.copyOf(value,
                newCapacity(minimumCapacity));
    }
}

If the length of the passed string + the length of the stored character of the array > the length of the array, then data expansion is needed.

/**
 * Returns a capacity at least as large as the given minimum capacity.
 * Returns the current capacity increased by the same amount + 2 if
 * that suffices.
 * Will not return a capacity greater than {@code MAX_ARRAY_SIZE}
 * unless the given minimum capacity is greater than that.
 *
 * @param  minCapacity the desired minimum capacity
 * @throws OutOfMemoryError if minCapacity is less than zero or
 *         greater than Integer.MAX_VALUE
 */
private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int newCapacity = (value.length << 1) + 2;
    if (newCapacity - minCapacity < 0) {
        newCapacity = minCapacity;
    }
    return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
        ? hugeCapacity(minCapacity)
        : newCapacity;
}

The expansion rule is as follows: by default, the array length is set to "(current array length * 2) + 2". However, if the expanded array is not enough to add new strings, the length of the array needs to be set to "character length in the array + string length passed".

So if we know that the length of the mosaic string is about 100 characters, we can set the initial length 150 or 200, which can avoid or reduce the number of array expansion, thereby improving efficiency.

Summary

In this paper, the invariability, basic principles and memory stack situation of String are analyzed, common methods, the creation of String Buffer and String Builder, and the principle of append method are explained. The similarities and differences between String, String Buffer and String Builder are compared. If there are any mistakes, please criticize and correct them. Thank you.

Keywords: PHP Java less

Added by domainshuffle on Thu, 20 Jun 2019 03:12:45 +0300