String is one of the core classes in java programming language. It is widely used and widely used.
But do you know what is the direct string volume? Do you know there is a string resident pool? The string resident pool can be used to cache the direct string volume.
What is a direct volume?
Direct Volume refers to the value directly specified through source code in a program.
Eg:
Int personId = 8080;
String name = "fancy ";
For the direct amount of strings in java, JVM uses a string resident pool to cache them. Generally, string objects in the string resident pool are not recycled by GC (Garbage Collection, Garbage Collection,
When you use a string to reside in an existing String object in the pool again, you do not need to create it again, but directly direct its reference variable to the existing String object in the string resident pool.
String basics:
The String class represents a String. Strings are constants and their values cannot be changed after they are created. In java, besides synchronized, immutable classes are thread-safe,
Therefore, the String class itself is thread-safe. Instance objects of the String class can be shared.
Sample Code:
1
2 String name = "fancy"; // @ 1
3 String nick = "fancydeepin"; // @ 2
4 name = nick;
5 System. out. println (name); // export: fancydeepin
6
Result output: fancydeepin
What's going on? Isn't String an immutable String? Why has it changed again?
In this case, name is just a reference type variable and is not a String object. @ 1 creates a "fancy" String object,
@ 2 creates a "fancydeepin" String object. name Reference (just like a pointer) points to the "fancy" object at the beginning. Then, the name points to the "fancydeepin" object again,
In the sample code, only two String objects are created throughout the process (I don't know if you can understand this. Why only two String objects are created? Instead of 1 or 3... @ 3 ),
One is the "fancy" object, and the other is the "fancydeepin" object. These two objects have not been changed since they were created. The reason why the program outputs fancydeepin is because
The object pointed to by name reference has changed.
If you look at my post with a serious attitude and are careful with you, will you pay attention to the following:
When the name reference points to another object again, how does the JVM handle the object referenced before name ("fancy" Object) at the underlying level? Will it be recycled immediately to release system resources?
The answer is no. Although the program no longer accesses the "fancy" object at this time, the JVM will not recycle it and it will stay in the memory for a long time during the program running. Why?
Let's move on to java's memory management mechanism, which is just a few minutes away. Here you can simply understand it as a "fancy" object that has been cached (actually because it has been cached ).
String resident pool
When comparing two String objects, should I use "=? Or should we choose equals? I believe that most people often use the equals method.
"=" And equals usage I believe everyone is familiar with it. "=" compares the two objects to see if their hash values are equal, equals compares whether the object content is the same.
In most cases, when comparing two String objects, we just want to compare whether their content is equal. In this case, we can only select equals, but is it true?
The answer is no. You can also use "=" to accomplish such a task, and "=" is more efficient than equals, provided that,
You must use the resident pool of the string to use "=" to replace equals for comparison.
There is a method named intern () in String, which is very efficient in execution, but you may not have used it yet. The following is a description of the intern () method in the API:
"When the intern method is called, if the pool already contains a String equal to this String Object (determined by the equals (Object) method), the String in the pool is returned.
Otherwise, this String object is added to the pool and a reference to this String object is returned. It follows the following rules:
For any two strings s and t, if and only when s. equals (t) is true, s. intern () = t. intern () is true. "
Sample Code:
1
2 String name = new String ("fancy ");
3
4 if (name = "fancy") {// false
5 System. out. println ("equals 1 ");
6} else {
7 System. out. println ("not equals 1"); // Be printed
8}
9
10 name = name. intern (); // Add the string to the resident pool
11
12 if (name = "fancy") {// true
13 System. out. println ("equals 2"); // Be printed
14} else {
15 System. out. println ("not equals 2 ");
16}
17
Output result:
1
2not equals 1
3 equals 2
4
As shown in the sample code above, it is very simple to use the string resident pool, and objects in the pool can be shared. As long as you add strings to the pool, you can directly use
"=" To compare two objects, instead of using equals for comparison. Adding strings to the resident pool for comparison with "=" is more efficient than directly using equals.
Let's talk about String, StringBuffer, and StringBuilder.
The method modified by synchronized can ensure the thread safety of the method, but it will reduce the execution efficiency of the method;
Open the API and it is easy to know that StringBuffer is a variable string sequence of thread security, and StringBuilder is a variable character sequence, which is thread unsafe;
The so-called use of StringBuffer on the Internet is more efficient and better, which is out of date. This is a saying in versions earlier than java 1.5, and it is outdated now !!
Now, StringBuilder is more efficient than StringBuffer because it is not thread-safe.
You may not trust what I said, but you should always trust the result of the program running. The following is the sample code:
1
2 StringBuffer buffer = new StringBuffer ();
3 StringBuilder builder = new StringBuilder ();
4 int COUNT = 10; // test COUNT
5 final int N = 100000; // N operations per trip
6 double beginTime, costTime; // start time and time consumed for each trip
7 double bufferTotalTime = 0.0D, buliderTotalTime = 0.0D; // The total time consumed by StringBuffer and StringBuilder to test COUNT
8 while (COUNT -->-1 ){
9 // You can also test whether a new object is created for each trip. This makes StringBuilder more efficient than StringBuffer.
10 /**
11 StringBuffer buffer = new StringBuffer ();
12 StringBuilder builder = new StringBuilder ();
13 */
14 System. out. println ("---------------------------------- <" + (COUNT + 1) + "> ");
15 beginTime = System. currentTimeMillis ();
16 for (int I = 0; I <N; I ++ ){
17 buffer. append (I );
18 buffer. length ();
19}
20 costTime = System. currentTimeMillis ()-beginTime;
21 bufferTotalTime + = costTime;
22 System. out. println ("StringBuffer time-consuming: --->" + costTime );
23 beginTime = System. currentTimeMillis ();
24 for (int I = 0; I <N; I ++ ){
25 builder. append (I );
26 builder. length ();
27}
28 costTime = System. currentTimeMillis ()-beginTime;
29 buliderTotalTime + = costTime;
30 System. out. println ("StringBuilder time-consuming: --->" + costTime );
31 System. out. println ("---------------------------------- <" + (COUNT + 1) + "> ");
32}
33 System. out. println ("bufferTotalTime/buliderTotalTime =" + (bufferTotalTime/buliderTotalTime ));
34
Background output result:
1
2 ---------------------------------- <10>
3 StringBuffer time-consuming: ---> 32.0
4 StringBuilder time-consuming: ---> 16.0
5 ---------------------------------- <10>
6 ---------------------------------- <9>
7 StringBuffer time-consuming: ---> 21.0
8 StringBuilder time-consuming: ---> 15.0
9 ---------------------------------- <9>
10 ---------------------------------- <8>
11 StringBuffer time-consuming: ---> 25.0
12 StringBuilder time-consuming: ---> 35.0
13 ---------------------------------- <8>
14 ---------------------------------- <7>
15 StringBuffer time-consuming: ---> 24.0
16 StringBuilder time-consuming: ---> 8.0
17 ---------------------------------- <7>
18 ---------------------------------- <6>
19 StringBuffer time-consuming: ---> 48.0
20 StringBuilder time-consuming: ---> 38.0
21 ---------------------------------- <6>
22 ---------------------------------- <5>
23 StringBuffer time-consuming: ---> 22.0
24 StringBuilder time-consuming: ---> 8.0
25 ---------------------------------- <5>
26 ---------------------------------- <4>
27 StringBuffer time-consuming: ---> 23.0
28 StringBuilder time-consuming: ---> 9.0
29 ---------------------------------- <4>
30 ---------------------------------- <3>
31 StringBuffer time-consuming: ---> 25.0
32 StringBuilder time-consuming: ---> 7.0
33 ---------------------------------- <3>
34 ---------------------------------- <2>
35 StringBuffer time-consuming: ---> 23.0
36 StringBuilder time-consuming: ---> 7.0
37 ---------------------------------- <2>
38 ---------------------------------- <1>
39 StringBuffer time-consuming: ---> 78.0
40 StringBuilder time-consuming: ---> 59.0
41 ---------------------------------- <1>
42 ---------------------------------- <0>
43 StringBuffer time-consuming: ---> 21.0
44 StringBuilder time-consuming: ---> 11.0
45 ---------------------------------- <0>
46 bufferTotalTime/buliderTotalTime = 1.6056338028169015
47
In the test, the average time consumed by StringBuffer is more than 1.6 times that of StringBuilder, and more than 1.6 times that of StringBuilder. The performance of StringBuffer and StringBuilder is better and clearer at a glance.
Finally, if you want to know the result of @ 3 (marked in red bold above), you may say:
Eg:
String mail = "fancydeepin" + "@" + "yeah.net ";
Let's take a look at the preceding statement. How many String objects will this statement create?
1? 2? 3? 4? Five? ......
Maybe you will think of four, they are: "fancydeepin", "@", "yeah.net", "fancydeepin@yeah.net"
Maybe you will think of five, they are: "fancydeepin", "@", "yeah.net", "fancydeepin @", "fancydeepin@yeah.net"
Maybe ......
But in fact, this statement only creates a String object!
Why? The reason is very simple, this is because the mail value has been determined at the time of compilation, it is "fancydeepin@yeah.net ".
When the program is running and the preceding statement is executed, the object referenced by mail will be created, and the mail value has been determined during compilation.
It is "fancydeepin@yeah.net", so eventually only one String object is created, and this object is the "fancydeepin@yeah.net" object. Www.2cto.com
Can this explanation be understood? Do you really understand it? It's really easy to understand. Let's look at it again:
Eg:
String mail = new String ("fancydeepin@yeah.net ");
How many objects have been created this time?
The answer is two. Why not one? Which two are the two?
They are: fancydeepin@yeah.net, new String ()
This is because the value of mail cannot be determined at the time of compilation. The compilation only translates the source code into bytecode, and the program has not run yet, so it cannot create new objects,
Therefore, the mail value cannot be determined after compilation.
When the program is running and the above statement is executed, this time to determine the reference object of mail, first, the "fancydeepin@yeah.net" object will be created,
Then execute new String (). Therefore, this statement creates two String objects.
By fancydeepin