1. The source string

 private final char value[];

A char[] array that is modified by the final keyword, so implementation details are not allowed to change, which is the Immutable property of the String class. Every operation on a String generates a new String, which is inefficient and wastes a lot of memory.

Case study:

String string ="abc";

string+="def";

String String =” ABC “;

String +=”def” (string+=”def”); string+=”def” (string+=”def”); abcDEF (string+=”def”); You can see that executing such a short two lines of code requires the heap to open up memory space three times, resulting in a significant waste of memory space resources.

Can the String class be inherited? Why is that?

The Java keyword final has the meaning “this cannot be changed” or “final state” and can be used to modify non-abstract classes, non-abstract class member methods, and variables. You may need to prevent change for two reasons: design or efficiency.

Final classes cannot be inherited, there are no subclasses, and methods in final classes are final by default.

Final methods cannot be overridden by subclass methods, but can be inherited.

Final member variables represent constants and can only be assigned once, after which the value does not change.

Final cannot be used to modify constructors.

Note: Private member methods of a parent class cannot be overridden by subclass methods, so methods of private type are final by default.

String source code has hash:

private int hash; public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; } why is hashCode () computed when h == 0? H is an int value and the default value is 0, so 0 can mean that the hash has not been performed, but it cannot mean that the hash has not been performed, because we are not sure whether the hash will produce a value of 0. Does the hash result in a hash value of 0? According to the hash calculation logic, when val[0] = 0, h = 31 * h + val[I] is calculated, and h is equal to 0. Val [0] = 0. The ASCII value of null is 0. Obviously, null can never be stored in val[0], so no value of 0 will be generated after hash calculation, and h == 0 can be used as the judgment condition of whether hash calculation has been performed. Value. length > 0: That is, if the length of the string is 0, no hash is performed.Copy the code

There is a private instance field hash in the String class that represents the hash value of the String. On the first call to the hashCode method, the hash value of the string is computed and assigned to the hash field. Subsequent calls to the hashCode method return the hash field directly. The initial hash value is 0.

Hash code for String is val[0]*31^(n-1) + val[1]*31^(n-2) +… + val[n-1], where val is the char array corresponding to the string. So a hashCode() call to a String with the same content will return the same value. On the other hand, the same hashCode() may not be returned with the same string content, because the above method may overflow when evaluating hashCode.

Run example:

String name = "che";

value = {'c', 'h', 'e'};

hash = 0;

value.length = 3;

// Execute logic:

val = value;

val[0] = "c";

val[1] = "h";

val[2] = "e";

h = 31 * 0 + c = c;

h = 31 * (31 * 0 + c) + h = 31 * c + h;

h = 31 * (31 * (31 * 0 + c) + h) + e = 31 * 31 * c + 31 * h + e;

Why is the value of 31?

Mainly because 31 is an odd prime number, so 31* I =32* I – I =(I <<5)-i, this displacement and subtraction combined calculation is much faster than the general operation.

Prime number: a natural number greater than 1 that is not divisible by any other natural number except 1 and the integer itself.

Due to the nature of prime numbers, the result of multiplying prime numbers is more likely to be unique than other methods, which means that the probability of producing hash values is lower.

The binary of 31 is: 11111, occupying five binary bits, which can be converted to (x << 5) -x during multiplication. There is a factor of multiplication, which in Java can result in an overflow of memory, resulting in data loss.

Large numbers run out of memory when multiplied, and 17 is a prime number, so why not 17?

I’m in the loop, too. A quick summary of 31:31 is a prime number, and multiplying it by a prime is more likely to produce uniqueness than the other way around. In Java, if the numbers multiplied are too large, memory overflow problems can result in data loss. Consider the value of this factor based on the above two aspects.

For specific research on the selection of 31 prime numbers, please refer to:

Blog.csdn.net/steveguosha…

Blog.csdn.net/tayanxunhua…

Stackoverflow.com/questions/2…

private static final ObjectStreamField[] serialPersistentFields =    new ObjectStreamField[0];
Copy the code

Serialization to include the domain, in serialization source code in detail, serialization function. It should be clear that transient is used to specify which fields will not be serialized by default. For attributes that do not need serialization, just use transient. SerialPersistentFields specifies which fields need to be serialized by default

  • Strings and characters

1

1“. public String(“char“[] value); // constructor

Convert an entire character array to a string;

1

2“. public String(“char“[] value, int offset, int count); ‘// constructor

Convert part of a character array to a string;

1

3“. public char charAt(“int index); // Common method

Gets the index character at the specified position.

1

4“. public char“[] toCharArray(); // Common method

Returns the data in the string as an array of characters;

  • Strings and bytes

Main purpose: binary data transmission, or encoding conversion.

1

1“. public String(“byte“[] bytes); // constructor

Turn an entire byte array into a string;

1

2“. public String(“byte“[] bytes, int offset, int length); ‘// constructor

Convert part of the byte array to a string;

1

3“. public byte“[] getBytes(); // Common method

Convert strings to byte arrays;

1

4“. public byte“[] getBytes(String charsetName) throws UnsupportedEncodingException; // Common method

On string judgment:

public boolean equals(String anObject); // Common method

If (this == anObject) {if (this == anObject) { If (anObject instanceof String) {if (anObject instanceof String) {if (anObject instanceof String) In the object types But only the String class or is the String class parent class can be true if (n = = anotherString. Value. Length) {/ / whether the length is consistent In order to speed up judgment // Check whether each bit of the same string is the sameCopy the code

RegionMatches: A substring used to compare the specified region in two strings

public boolean regionMatches(int toffset, String other, int ooffset, int len) { char ta[] = value; int to = toffset; char pa[] = other.value; int po = ooffset; // Note: toffset, ooffset, or len might be near -1>>>1. if ((ooffset < 0) || (toffset < 0)|| (toffset > (long)value.length - len)|| (ooffset > (long) other.value.length-len)) {return false; } while (len-- > 0) { if (ta[to++] ! = pa[po++]) {// loop over a single character return false; } } return true; } toffSET - The starting offset of the toffset field of this string. Other - String parameter. Ooffset - The starting offset of the ooffset field for the string argument. Len - The number of characters to compare. Public Boolean regionMatches(Boolean ignoreCase, int toffSet,String Other, int ooffSet, int Len) {//ignoreCase ignores caseCopy the code
  • String lookup

Finds the existence of substrings from a complete string

1

1“. public boolean contains(String s); // Common method

Determine whether a substring exists;

1

2“. public int indexOf(String str); // Common method

Find string from scratch, return -1;

1

3“. public int indexOf(String str, int fromIndex); // Common method

Finds substrings from the specified index position;

1

4“. public int lastIndexOf(String str); // Common method

Find substrings backwards;

1

5“. public int lastIndexOf(String str, int fromIndex); // Common method

Finds substrings backwards from the specified position;

1

6“. public boolean startsWith(String prefix); // Common method

Determines whether to start with the specified string.

1

7“. public boolean startsWith(String prefix, int toffset); // Common method

Determines whether to start with the specified string from the specified position.

1

8“. public boolean endsWith(String suffix); // Common method

Determines whether to end with the specified string.

  • String substitution

1

1“. public String replaceAll(String regex, String replacement); // Common method

Replace all;

1

2“. public String replaceFirst(String regex, String replacement); // Common method

Replace the first;

  • String splitting

The split data is returned as an array of strings.

1

1“. public String[] split(String regex); // Common method

Split according to the specified string;

1

2“. public String[] split(String regex, int limit); // Common method

Split the string into the specified number;

String interception

1

1“. public String substring(“int beginIndex); // Common method

Intercepts from the specified index to the end of the string;

1

2“. public String substring(“int beginIndex, int endIndex); // Common method

Intercepts a string in the specified index range;

Other methods

1

1``. public String concat(String str);

String concatenation;

1

2``. public String intern();

A string is pooled.

1

3``. public boolean isEmpty();

Determines whether the string is empty;

1

4``. public int length();

String length;

1

5``. public String trim();

Remove the left and right Spaces of the string;

1

6``. public String toUpperCase();

Turn to capital;

1

7``. public String toLowerCase();

Turn to lowercase.

Here these basic methods are not introduced, look at the basic code can understand.

2. The stringbuffer source code

Stringbuffer inherits the AbstractStringBuilder class.

public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence private transient char[] toStringCache; Public synchronized StringBuffer appEnd (String STR) {toStringCache = null; super.append(str); return this; }public synchronized StringBuffer insert(int offset, String str) { toStringCache = null; super.insert(offset, str); return this; }Copy the code

Transient: Java’s TRANSIENT keyword provides convenience. You only need to implement Serilizable interface and add the keyword TRANSIENT to attributes that do not need to be serialized. When you serialize an object, the attributes will not be serialized to the specified destination.

Synchronized: ensures thread security

There are append, DELETE, replace, INSERT, and so on.

AbstractStringBuilder AbstractStringBuilder

Expansion method

private void ensureCapacityInternal(int minimumCapacity) {

// overflow-conscious code

if (minimumCapacity - value.length > 0)

value = Arrays.copyOf(value, newCapacity(minimumCapacity));

}

private void newCapacity(int minimumCapacity) {

int newCapacity = value.length * 2 + 2; // Make it 2 times 2

If (newCapacity - minimumCapacity < 0) // If the new length is still smaller than the minimum length, set the new length to the minimum length

newCapacity = minimumCapacity;

If (newCapacity < 0) {// The new length is negative, exceeding the maximum value of int

If (minimumCapacity < 0) // overflow //

throw new OutOfMemoryError();

newCapacity = Integer.MAX_VALUE; // If the minimum length does not exceed the maximum value int, but the original length exceeds the maximum value int by multiplying the original length by 2, then the new length is assigned to the maximum value int

}

value = Arrays.copyOf(value, newCapacity); // Call arrays.copyof to generate a new length array

}

Private int newCapacity(int minCapacity) {// overflow-conscious code

int newCapacity = (value.length << 1) + 2; // Bitwise calculation is faster,

if (newCapacity - minCapacity < 0) {

newCapacity = minCapacity;

}

return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0) ? hugeCapacity(minCapacity) : newCapacity; }

private int hugeCapacity(int minCapacity) { if (Integer.MAX_VALUE - minCapacity < 0) { // overflow throw new OutOfMemoryError(); } return (minCapacity > MAX_ARRAY_SIZE) ? minCapacity : MAX_ARRAY_SIZE; }Copy the code

Add null, Boolean, char, char [] and so on to the append method.

Delete:

public AbstractStringBuilder delete(int start, int end) { if (start < 0) throw new StringIndexOutOfBoundsException(start); if (end > count) end = count; if (start > end) throw new StringIndexOutOfBoundsException(); int len = end - start; if (len > 0) { System.arraycopy(value, start+len, value, start, count-end); //start + len moves the element forward by len -= len; } return this; }Copy the code

Insert:

public AbstractStringBuilder insert(int offset, String str) {
    if ((offset < 0) || (offset > length())) 
       throw new StringIndexOutOfBoundsException(offset);
    if (str == null)
        str = "null";
    int len = str.length();
    ensureCapacityInternal(count + len);
    System.arraycopy(value, offset, value, offset + len, count - offset);
    str.getChars(value, offset);
    count += len;
    return this;
}
Copy the code

reverse:

public AbstractStringBuilder reverse() {
    boolean hasSurrogates = false;
    int n = count - 1;
    for (int j = (n-1) >> 1; j >= 0; j--) {
        int k = n - j;
        char cj = value[j];
        char ck = value[k];
        value[j] = ck;
        value[k] = cj;
        if (Character.isSurrogate(cj) || Character.isSurrogate(ck)) {
            hasSurrogates = true;
        }
    }
    if (hasSurrogates) {
        reverseAllValidSurrogatePairs();
    }
    return this;
}
Copy the code

The stringbuilder source

The StringBuilder class represents a mutable sequence of characters. StringBuilder’s API is compatible with StringBuffer, but StringBuilder is not thread-safe. Where possible, StringBuilder is preferred because it is faster than StringBuffer in most implementations.

Much of the code is the same as stringBuffer, except that there is no synchronized.

Execution speed:

stringbuilder > stringbuffer > string 

On thread safety:

StringBuffer is thread-safe, StringBuilder is non-thread-safe;

Usage Scenarios:

String is suitable for a small number of string operations;

Stringbuilder is suitable for single-threaded downloading of character buffers for large operations;

Stringbuffers are suitable for large numbers of operations on character buffers in multiple threads;