Introduction to the String class

The API describes it this way: The String class represents a String. All string literals in Java programs, such as “ABC”, are implemented as instances of this class. Strings are constants; Their values cannot be changed after they are created. The string buffer supports mutable strings. Because strings are immutable, they can be shared.

1. The String class diagram

The String class implements three interfaces: Serializable, Compareable, and CharSequence.

With the Serializable interface, there are no methods that need to be implemented; the interface is only used to indicate that Serializable methods can be implemented.

For the Compareable interface, there is only one method public int compareTo(T o); This method is mainly used for comparison.

For CharSequence, it is an interface that describes the structure of a string and defines the most basic operations of the string

2. Analyze Srting source code

/** String attribute value */  
    private final char value[];

    /** The offset is the first index of the storage that is used. */
    /** The beginning of the array used **/
    private final int offset;

    /** The count is the number of characters in the String. */
    /** Number of elements in String **/
    private final int count;

    /** Cache the hash code for the string */
   /** Hash value of String **/
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;
    /**
     * Class String is special cased within the Serialization Stream         Protocol.
     *
     * A String instance is written into an ObjectOutputStream according to
     * <a href="{@docRoot} /.. / platform/serialization/spec/output. The HTML "> * Object serialization Specification, Section 6.2," Stream Elements "< / a > * /privatestatic final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

Copy the code
  1. From the source code, the String effect is the same as the char[] character array, but the underlying principle of String is the byte[] byte array to maintain.
  2. As you can see from the member variable, the String value is final and cannot be changed, so strings can be shared.
  3. If a value is changed, a new String object is generated. The String data is stored not necessarily at the 0th element of the array, but at the element indicated by offset.

3. The constructor of String

  • String() initializes a newly created String to represent a sequence of null characters.

  • String(byte[] bytes) Constructs a new String by decoding the specified array of bytes using the platform’s default character set.

  • String(byte[] bytes, Charset Charset) Constructs a new String by decoding the specified array of bytes using the specified Charset.

  • String(byte[] bytes, int offset, int Length) Constructs a new String by decoding the specified byte subarray using the platform’s default character set.

  • String(byte[] bytes, int offset, int Length, Charset Charset) Constructs a new String by decoding the specified byte subarray using the specified Charset.

  • String(byte[] bytes, int offset, int Length, String charsetName) Constructs a new String by decoding the specified byte subarray using the specified character set.

  • String(byte[] bytes, String charsetName) Constructs a new String by decoding the specified array of bytes using the specified charset.

  • String(char[] value) Allocates a new String that represents the sequence of characters currently contained in the character array argument.

  • String(char[] value, int offset, int count) allocates a new String that contains the characters from a subarray of the character array argument.

  • String(int[] codePoints, int offset, int Count) allocates a new String that contains a subarray of characters from the Unicode codePoints group argument.

  • String(String Original) Initializes a newly created String that represents the same sequence of characters as the argument; In other words, the newly created string is a copy of the parameter string.

  • String(StringBuffer buffer) Allocates a new String that contains the sequence of characters currently contained in the String buffer argument.

  • String(StringBuilder Builder) Allocates a new String that contains the sequence of characters currently contained in the String generator argument.

4.String class instantiation and memory resolution

4.1 Direct Assignment to Instantiate a String

An object created by direct assignment is a constant pool in the method area

Note that the location of the string constant pool changed in JDK 1.7:

  • Prior to JDK 1.7, string Constant pools existed in Constant storage

  • After JDK 1.7, the pool of string constants exists in the Heap

  • Str1 creates a new String in the heap, and since str2 and STR3 directly assign to the same String “hello”, the String is added to the JVM’s “object pool”. All three references refer to the same String in the “object pool”, so “==” is true.

4.2 Instantiate a String with the new constructor ()

The string object is created by the constructor in heap memory

  • Since “Hello “(anonymous object of String literal constant /String) is also a String, the JVM creates a “hello” String in the heap memory space, copies the String and points to it by STR. This results in garbage space, which is automatically reclaimed by the JVM. And if the constructor is used, the string object will not be added to the JVM’s “string constant pool,” causing string sharing problems.
To solve the “String sharing” problem, you can use the String classinternMethods toConstructors create strings that are manually added to the "String constant pool". (Constructor instantiation does not pool the String by default)

4.3 summarize

  • Direct assignment: only a chunk of heap memory space is created, and the string object can be automatically stored in the object pool for next use.
  • The new construct () method: creates two heap Spaces, one of which becomes garbage space and is not automatically stored in the object pool by default. It can be pooled manually using the intern() method.
  • Summary: Using constructors to instantiate objects, even if manually pooled using the intern() method, does not solve the garbage space problem, so useDirect assignmentTo create a String object.

4.4 Avoid null pointing

“==” compares a memory address when comparing a string; The equals() method compares the contents of a string.

  • The equals() method avoids null points by taking arguments.
String str = null;if(str.equals("hello")) {// A null pointing exception occurs. }if("hello".equals(str)){// In this case, equals will handle the null value, so as to avoid null pointing exceptions. }Copy the code

2. Common String methods

The retrieval

  • Int length () gets the length of the string;

  • Char charAt(int index) Retrieve the character at the specified index;

  • Int indexOf(String STR) Int indexOf(String STR) Int indexOf(String STR) int indexOf(String STR)

  • String substring(int start) Truncates a String from index start to end;

  • String substring(int start, int end) Intercepts a String from index start (including start) to end (excluding end).

Judge operation

  • Boolean equals(Object obj) to compare whether the contents of a string are the same (case sensitive);

  • Boolean equalsIgnoreCase(String STR) compares whether the contents of a String are the same (case ignored);

  • Boolean startsWith(String STR) determines whether the character object startsWith the specified STR;

  • Boolean endsWith(String STR) determines whether a character object endsWith a specified STR;

  • Boolean contans (CharSequence cs) Determines whether this string contains the specified character sequence;

  • Boolean isEmpty () Currently returns true only if the string length is 0;

Conversion operations

  • Char [] toCharArray() converts a string to an array of characters;

  • String toLowerCase() converts a String toLowerCase;

  • String toUpperCase() converts the String toUpperCase;

  • String valueOf (int I) converts an int to a String;

Intercept and split operations

  • String[] split (String regex) Split the original String into several strings according to the regex argument;

  • String substring(int beginIndex) Intercepts all characters after the secondary index beginIndex.

  • String Substring (beginIndex, endIndex) Intercepts the characters between beginIndex and endIndex.

Other methods

  • String trim() Removes whitespace from both ends of the String;

  • String replace(char oldChar, char newChar) returns a new String, which is obtained by replacing all oldChar occurrences in the String with newChar;

  • The Boolean matches(String regex) tells you whether this String matches the given regular expression;

String class, StringBuffer class, StringBuilder class

1. StringBuffer and StringBuilder class diagrams

1.1 Variable StringBuffer and StringBuilder

Similarities:

  • Both StringBuffer and StringBulider represent mutable string objects and both inherit from the common parent class AbstractStringBuilder.

  • StringBuffer and StringBulider are very similar in that they provide the same functionality;

Similarities and differences:

  • StringBuffer is thread safe; Multithreaded environments use StringBuffer for frequently changing strings; All methods are usedsynchronizedKeyword for synchronization.

  • StringBuilderr is not thread safe; Single-threaded frequently changing strings use StringBuilder; Method is uselesssynchronizedKeyword for synchronization.

1.2 Immutable Strings and mutable StringBuffers

The String class is immutable, meaning that once a String is created, the sequence of characters contained in it is immutable until the object is destroyed.

The StringBuffer object represents a string with a variable sequence of characters. When a StringBuffer is created, The StringBuffer provides methods such as Append (), insert(), reverse(), setCharAt(), setLength(), and so on to change the sequence of characters in the string object. Once the final desired String has been generated from the StringBuffer, it can be converted to a String by calling its toString() method.

1.3 Differences among the three

Four, often meet pilot

(1) Can strings be inherited?

Cannot be inherited because the String class has a final modifier, and final modifiers cannot be inherited.

(2)Why are strings designed to be immutable, and how are they guaranteed to be?

In Java, the String class is designed to be immutable, mainly because the member variables that hold the String are final.

  • Prior to Java 9, strings used char[] arrays to hold characters, private final char[] value;

  • Java 9 improved the use of byte[] arrays to hold characters, private final byte[] value;

How to guarantee immutable?

Considering a variety of factors in Java requires a combination of memory, data structure, and security considerations.

  • String constant pool needs:

The string constant pool is only meaningful when the string is immutable. The presence of a string constant pool reduces the number of strings created with the same literal and allows different references to the same string in the pool, saving a lot of heap memory at runtime. If the String is mutable, the String constant pool is meaningless, and the string.intern () method based on the constant pool is invalid. Every time a new String is created, it opens up new space in the heap, taking up more memory.

  • Run String cache HashCode:

Strings, as the basic data structure, are widely used in some collection containers, especially hash sets, where the location of elements is determined by the object’s hashCode() method. Since the string hashcode property does not change, the uniqueness is guaranteed, and only containers such as HashMap and HashSet can realize the corresponding caching function. Because strings are immutable, you can avoid calculating hashCodes twice and just use cached Hashcodes, which greatly improves the performance of using strings in hash collections.

  • Thread safety:

In multithreading, only immutable objects and values are thread-safe, and data can be shared among multiple threads. Since strings are inherently immutable, when a thread “modifiers” the value of a String, only a new String object is created. There is no side effect to other threads accessing the same String data without any synchronization.

  • Information Security:

Because of the String, no matter in any Java system widely used, will be used to store sensitive information, such as account number, password, network paths, file processing etc. Scene, guarantee the safety of String String class is particularly important, if the String is variable, and easy to tamper with, that we cannot guarantee when using String manipulation, It is safe, and there is a good chance of SQL injection, accessing dangerous files, and so on.

(3) Say what you understand about string concatenation!

1. Use the + operator to concatenate strings:

If all the concatenations are strings that are direct constants, then at compile time the compiler will optimize it directly to a complete string, just as if you were writing a complete string, so it’s very efficient.

If the concatenated strings contain variables, the compiler optimizes them with StringBuilder at compile time by automatically creating a StringBuilder instance and calling its append() method to concatenate the strings together efficiently. But if the concatenation is done in a loop, then each time the compiler creates a StringBuilder instance and concatenates the string, it executes new StringBuilder().append(STR), which is inefficient.

String chenmo = "Silence";
String wanger = "Two";

System.out.println(chenmo + wanger);

Copy the code

2. Use StringBuilder/StringBuffer together string:

StringBuilder/StringBuffer has a string buffer, buffer capacity determine when creating objects, and the default is 16. When the concatenated string exceeds the buffer capacity, the buffer expansion mechanism is triggered, that is, the buffer doubling.

Frequent buffer expansion reduces concatenation performance. Therefore, if the length of the final string can be estimated in advance, it is recommended that you do not use the default capacity when creating variable string objects. Instead, you can specify the buffer capacity as the estimated string length.

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


public synchronized StringBuffer append(String str) { 
    toStringCache = null; 
    super.append(str); 
    return this; 
}
Copy the code

Concat (String) concat (String)

The concatenation logic of the concat method is to create an array of bytes large enough to hold the two strings to be concatenated, then to spell the two strings into the array, and finally to convert the array to strings.

Concat is less efficient than StringBuilder when concatenating large numbers of strings. However, concat is more efficient than StringBuilder when concatenating only two strings. Since the concat method is simple, it is recommended to use the concat method when only two strings are spelled.

String chenmo = "Silence";
String wanger = "Two";

System.out.println(chenmo.concat(wanger));

Copy the code

4. When joining a String using the join method of String class:

JDK 1.8 provides a new string concatenation join method.

public static String join(CharSequence delimiter, CharSequence... elements) {
    Objects.requireNonNull(delimiter);
    Objects.requireNonNull(elements);
    // Number of elements not likely worth Arrays.stream overhead.
    StringJoiner joiner = new StringJoiner(delimiter);
    for (CharSequence cs: elements) {
        joiner.add(cs);
    }
    return joiner.toString();
}

Copy the code