Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article also participated in the “Digitalstar Project” to win a creative gift package and creative incentive money

Let’s talk about the three public methods of String

1, intern() method use, first look at the source (jdk1.8) :

/** JDK 1.8 * Returns a canonical representation for the string object. * <p> is maintained privately by the * class {@code String}. * <p> * When the intern method is invoked, if the pool already contains a * string equal to this {@code String} object as determined by * the {@link #equals(Object)} method, then the string from the pool is * returned. Otherwise, this {@code String} object is added to the * pool and a reference to this {@code String} object is returned. * <p> * It follows that for any two strings {@code s} and {@code t}, * {@code s.intern() == t.intern()} is {@code true} * if and only if {@code s.equals(t)} is {@code true}. * <p> * All Literal strings and String-valued expressions are * interned. String literals are defined in section 3.10.5 of the * <cite>The Java&trade; Language Specification</cite>. * * @return a string that has the same contents as this string, but is * guaranteed to be from a pool of unique strings. */ public native String intern();Copy the code

As we know, this method is native and returns a reference to the string constant pool when it has the current string, which is consistent across JDK versions. If the string constant pool does not exist, the operations in the string constant pool differ as follows:

HashCode () {String ();

/**
 * Returns a hash code for this string. The hash code for a
 * {@code String} object is computed as
 * <blockquote><pre>
 * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
 * </pre></blockquote>
 * using {@code int} arithmetic, where {@code s[i]} is the
 * <i>i</i>th character of the string, {@code n} is the length of
 * the string, and {@code ^} indicates exponentiation.
 * (The hash value of the empty string is zero.)
 *
 * @return  a hash code value for this object.
 */
public int hashCode() {
    int h = hash; // #1 hash for what
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i]; // #2 why 31
        }
        hash = h;
    }
    return h;
}
Copy the code

After reading the above source code, you may have two questions:

1. What does hash do?

Hash is an int used to cache hashCode for strings.

2. Why is it 31 at #2?

To paraphrase Effective Java,

The value 31 was chosen because it is an odd prime. If it were even and the multiplication overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. The advantage of using a prime is less clear, but it is traditional. A nice property of 31 is that the multiplication can be replaced by a shift and a subtraction for  better performance: 31 * I == (I << 5) -i. Modern VMs do this sort of optimization automatically. // If an even number is selected, there will be an overflow in the multiplication operation, resulting in the loss of numerical information, because multiplication by two is equivalent to a shift operation. The advantages of choosing prime numbers are not particularly obvious, but it's a tradition. Also, the number 31 has the nice feature that multiplication can be replaced by shift and subtraction for better performance: 31 * I == (I << 5) -i, which modern Java virtual machines can do automatically.Copy the code

String equals(); String equals(); String equals();

public boolean equals(Object anObject) { if (this == anObject) { return true; // The same object returns true} 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; // Same string value, return true}} return false; }Copy the code

Second, why is String designed to be immutable?

First look at the source definition:

Public final class String // #1 Not allowed to be inherited java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; /** Use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L; // region omit other methods // ************* // endregion}Copy the code

There are three reasons why it’s immutable,

1. The need for a string constant pool

Immutable String values are a necessary condition for the implementation of String constant pooling.

2. Ensure that the hash value is unique

Enable the key-value function of the HasnMap class Map container.

3. Based on safety considerations

If variable, easily modified arbitrarily. Consider Using StringBuilder and StringBuffer for scenarios that need to change.

StringBuilder and StringBuffer

In conclusion, after exploring the secrets of String, let’s take a look at Java containers, such as the design and practice of List, Set, Map and other data structures.