1, Introduction to String class
The String class, located under the java.lang package, is the core class of the Java language. It provides String comparison, search, interception, case conversion and other operations. You can use "+" to connect other objects. Part of the source code of the String class is as follows
public final class String implements 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; // Default to 0 ... }
As can be seen from the above
- The String class is modified by the final keyword, which means that the String class cannot be inherited, and its member methods default to the final method; Once a String is created, it cannot be modified;
- String class implements Serializable, CharSequence and Comparable interfaces;
- The value of the s tring instance is stored through the character array;
2, "+" connector
1. Implementation principle of "+" connector
String connection is realized through StringBuilder (or StringBuffer) class and its append method. Object conversion to string is realized through toString method. This method is defined by object class and can be inherited by all classes in Java.
We can verify the following by decompiling:
public class Test { public static void main(String[] args) { int i = 10; String s = "nezha"; System.out.println(s + i); } } /** * After Decompilation */ public class Test { public static void main(String args[]) { ... byte byte0 = 10; String s = "nezha"; System.out.println((new StringBuilder()).append(s).append(byte0).toString()); } }
From the above code, we can see that the bottom layer of the "+" connection string is actually completed by the StringBuilder object through append and then calling toString.
2. Efficiency of "+" connector
When using the "+" connector, the JVM will implicitly create a StringBuilder object. This method will not cause efficiency loss in most cases, but it is different when splicing strings in a loop.
Because a large number of StringBuilder objects will be created in heap memory, which is certainly not allowed, it is recommended to create a StringBuilder object outside the loop, and then call the append method inside the loop for manual splicing.
In another special case, if "+" splices strings in string constants, the compiler will optimize and directly splice the two string constants.
Therefore, the "+" connector is very efficient for directly added string constants, because its value is determined during compilation; However, for indirect addition, the efficiency will become lower. It is recommended to use StringBuilder for single thread and StringBuffer for multithreading.
3, String, StringBuilder and StringBuffer
1. Main differences
- String is an immutable character sequence, and StringBuilder and StringBuffer are variable character sequences.
- Execution speed StringBuilder > StringBuffer > string.
- StringBuilder is non thread safe and StringBuffer is thread safe.
2. Efficiency test
import java.util.ArrayList; import java.util.List; import java.util.StringJoiner; public class StringTest { private static void test01() { String str = "nezha,"; String ret = ""; System.out.println("+String splicing start..."); long start = System.currentTimeMillis(); // +The efficiency in the cycle is too low. Use 100000 tests for (int i = 0; i < 100000; i++) { ret += str; } long end = System.currentTimeMillis(); System.out.println("+Time consuming for splicing 100000 pieces of data:"+(end-start)+"ms");//18288ms System.out.println("************"); } private static void test02() { String str = "nezha,"; StringBuilder builder = new StringBuilder(); System.out.println("StringBuilder,String splicing start..."); long start = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { builder.append(str); } long end = System.currentTimeMillis(); System.out.println("StringBuilder Splicing 10 million pieces of data takes time:"+(end-start)+"ms");//168ms,173ms,239ms System.out.println("************"); } private static void test03() { String str = "nezha,"; StringBuffer buffer = new StringBuffer(); System.out.println("StringBuffer,String splicing start..."); long start = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { buffer.append(str); } long end = System.currentTimeMillis(); System.out.println("StringBuffer Splicing 10 million pieces of data takes time:"+(end-start)+"ms");//527ms,343ms,398ms System.out.println("************"); } /** * StringJoiner The efficiency of is significantly higher than that of List + StringJoiner */ private static void test04() { String str = "nezha"; StringJoiner join = new StringJoiner(","); System.out.println("StringJoiner,String splicing start..."); long start = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { join.add(str); } long end = System.currentTimeMillis(); System.out.println("StringJoiner Splicing 10 million pieces of data takes time:"+(end-start)+"ms");//184ms,316ms,243ms System.out.println("************"); } private static void test05() { String str = "nezha"; List<String> list = new ArrayList<String>(); System.out.println("List + StringJoiner,String splicing start..."); long start = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { list.add(str); } String ret = String.join(",", list); long end = System.currentTimeMillis(); System.out.println("List + StringJoiner Splicing 10 million pieces of data takes time:"+(end-start)+"ms");//563ms,477ms,585ms System.out.println("************"); } public static void main(String[] args) { test02(); } }
3. Console output
Summary: StringBuilder has the highest efficiency and + splicing has the lowest efficiency.
4. Source code analysis
StringBuilder source code
@Override public StringBuilder append(char[] str) { super.append(str); return this; }
StringBuilder inherits the AbstractStringBuilder class
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence { ... }
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; }
append will directly copy characters to the internal character array. If the length of the character array is not enough, it will be extended.
The situation of StringBuffer is similar to that of StringBuilder, except that StringBuffer is thread safe.
4, String constant pool
1. Baidu Encyclopedia
Constant pool is used in java to save a copy of data in the compiled class file that has been determined at the compilation time. It includes constants in classes, methods and interfaces, as well as string constants, such as String s = "java"; Of course, it can also be expanded. The constants generated by the actuator will also be put into the constant pool. Therefore, it is considered that the constant pool is a special memory space of the JVM.
2. Object assignment of string
String object allocation consumes a lot of time and space, and strings are used very much. Many junior programmers will define all variables as string. I wonder if this was the case when you were young, ha ha.
In order to improve performance and reduce memory overhead, the JVM performs a series of optimizations when instantiating strings, that is, String constant pool. The JVM will first check the String constant pool. If it already exists, it will directly return the instance reference in the String constant pool. If it does not exist, it will instantiate the String and put it into the String constant pool. Due to the immutability of String, there must not be two identical strings in the constant pool.
3. Memory area
In the HotSpot VM, the String constant pool is implemented through a StringTable class, which is a Hash table. The default size length is 1009; This StringTable has only one copy in each HotSpot VM instance and is shared by all classes; The String constant consists of one character and is placed on the StringTable. It should be noted that if too many strings are put into the String Pool, the Hash conflict will be serious, resulting in a long linked list. The direct impact of a long linked list is that the performance will be greatly reduced when calling String.intern.
4. For example, it is clear at a glance
public class StringTest { public static void main(String[] args) { // 1. Create a new reference s1 to the object s1 in the heap with the value of "CSDN" String s1=new String("CSDN")+new String("nezha"); // 2. Create a new reference s2 to the object s2 in the heap with the value "CSDN" String s2=new String("CS")+new String("DN nezha"); // 3. Executing s1.intern() will create a new reference "CSDN Nezha" in the string constant pool, which points to the address of s1 in the heap, and a new reference s3 points to "CSDN Nezha" in the string constant pool String s3=s1.intern(); // 4. Executing s2.intern() will not create a new reference in the string constant pool, because "CSDN Nezha" already exists, so only the operation of creating a new reference s4 to "CSDN Nezha" in the string constant pool is performed String s4=s2.intern(); // s3 and s4 point to the "CSDN Nezha" in the string constant pool, and this "CSDN Nezha" points to the address of s1 in the heap System.out.println(s1==s3); // true System.out.println(s1==s4); // true // The address in the final Association heap of s3 and s4 is object s1 System.out.println(s2 == s3);// false System.out.println(s2 == s4);// false } }
5, intern() method
The String object declared directly in double quotation marks will be directly stored in the String constant pool. If it is not a String object declared in double quotation marks, you can use the intern method provided by String. The intern method is a native method. The intern method will query whether the current String exists from the String constant pool. If so, it will directly return the current String; If it does not exist, the current String will be put into the constant pool and returned later.
Changes to JDK1.7:
- Moved the String constant pool from the Perm area to the Java Heap area
- When using the String.intern() method, if there is an object in the heap, the reference of the object will be saved directly without re creating the object.
🔥 Contact the author, or scan the QR code of the home page and join us 🔥
Highlights of previous periods
Summary of 208 classic Java interview questions with 100000 words (with answers and suggestions)
Summary of MySql Basics (version 2021)
Summary of basic knowledge of MySql (SQL optimization)
[summary of the most complete Java framework in the whole stack] SSH, SSM, Springboot
Detailed explanation of springBoot Basics
Java design patterns: comprehensive analysis of 23 design patterns
Summary of common data structures and algorithms