The difference between the equals method and ==
First of all, everyone knows that String can be used both as an object and as a basic type. What is meant here is that using it as a basic type only refers to the usage method, such as String s = "Hello". It is used in the same way as the basic type int, such as int i = 1;, and using it as an object is Refers to creating a new object through the new keyword, such as String s = new String("Hello"). But its internal action actually creates an object, which will be discussed later.
Secondly, you need to understand the comparison method of String objects. There are two concepts for comparison between objects in Java. Here is the String object: one is to use "==" to compare. This comparison is for the references of two String type variables. That is to say, if two For String type variables, if they refer to the same String object (that is, point to the same memory heap), the result of the "==" comparison is true. The other is to use the equals() method of the Object object for comparison. The String object inherits from Object and the equals() method is overridden. When two String objects are compared through the equals() method, the string content encapsulated by the String object is actually compared. That is to say, if the string content encapsulated by the two String objects is the same (including the same case), Then the equals() method will return true.
Now we will start to do a detailed analysis of the creation of String objects:
1. //////////////////////////////// ///////////////////////////////////////////
String s1 = new String( "Hello");
String s2 = new String("Hello");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
The print result of the above code snippet is:
false
true
I believe this result is easy to understand. The two String type variables s1 and s2 each create a new String object through the new keyword. The new key Allocates a new, independent memory heap for each object created. Therefore, when comparing whether they refer to the same object through "==", false will be returned. When compared through the equals() method, true is returned because the string contents encapsulated by the two objects are exactly the same.
2、///////////////////////////////////////////////// /////////////////////////////////////
String s1 = new String("Hello");
String s2 = s1;
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
The printed result of the above code snippet is:
true
true
This result should be better understood. Variable s1 still creates a new String object through the new keyword, but here s2 does not create a new String object through the new keyword, but assigns s1 directly. To s2, the reference of s1 is assigned to s2, so the object referenced by s2 is actually the object referenced by s1. So when compared with "==", true is returned. Since they all refer to the same object, when compared through the equals() method, it will definitely return true. The equals() method here is actually comparing the same object, and it must be equal to itself.
3、//////////////////////////////////////////////// ////////////////////////////////
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
The printed result of the above code snippet is:
true
true
Why is this result? So let’s analyze it. First of all, these two String objects are used as a basic type, rather than created through the new keyword. Therefore, the virtual machine will not allocate a new memory heap for these two String objects, but to the String buffer pool. Come and find.寻 First look for S1 to find the String object with the same value as the "Hello" in the String buffer pool. At this time, the string buffer pool is empty, and there is no STRING object with the same value. , its action is new String("Hello");. Then assign the reference of this String object to s1.寻 Then find the STRING object with the same value as "Hello" in the S2 to find the String buffer pool. At this time, the virtual machine finds a String object with the same value. This String object is actually the String object created for S1. Now that an object with the same value is found, the virtual machine no longer creates a new String object for this purpose, but directly assigns the reference to the existing String object to s2.
Since s1 and s2 refer to the same String object, that is, they are equal to themselves, so the above two comparison methods return true.
At this point, you should have understood the basic concepts of String objects. Now let me summarize:
Using String as a basic type:
1. If String is used as a basic type, then we regard this String object as owned by the String buffer pool.
2. If String is used as a basic type, and there is no String object with the same specified value in the String buffer pool at this time, then the virtual machine will create a new String object for this and store it in the String buffer pool.
3. If String is used as a basic type, and there is a String object with the same specified value in the String buffer pool at this time, then the virtual machine will not create a new String object for this, but directly return a reference to the existing String object.
Use String as an object:
1. If String is used as an object, the virtual machine will create a new String object for it, that is, allocate a new memory heap for this object, and it is not owned by the String buffer pool, that is, it is independent.
After understanding the above, please look at the following code snippet:
4, ////////////////////////////////// //////////////////////////////////////////////
String s1 = "Hello";
String s2 = new String("Hello");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
Above The printed result of the code snippet is:
false
true
Analyzed based on the summary above. The first line uses String as a basic type, so the object referenced by s1 belongs to the String buffer pool. And at this time, there is no String object with the same value in the String buffer pool, so the virtual machine creates a new String object for this, namely new String("Hello");. The second line uses String as an object, so the object referenced by s2 does not belong to the String buffer pool, that is, it is independent. Through the new keyword, the virtual machine creates a new String object for this purpose, that is, allocates a new memory heap for it. Therefore, the result of "==" comparison is false, because s1 and s2 do not refer to the same object, they exist independently. The equals() method returns true because the string contents encapsulated by the two objects are exactly the same.
Now, I believe everyone has fully understood what the String object is:) But it does not end here, because the String object has deeper applications.
Here I will analyze the application of the intern() method of the String object:
intern() method will return the canonical representation of a string object, that is, a string with the same content as the string, but from a unique String buffer pool for strings. This sounds a bit mouthful, but in fact its mechanism is as follows:
String s = new String("Hello");
s = s.intern();
The function implementation of the above code snippet can be simply viewed into the following code segment:
String s = "Hello";
You must be wondering again? Then you can look at the second code snippet first. The meaning of the second code snippet is to take a reference to a String object with the same value from the String buffer pool and assign it to s. If there is no String object with the same value in the String buffer pool, a new String object is created in it. So what does the first piece of code mean? We know that for objects created through the new keyword, the virtual machine allocates a new memory heap for it. If you create an object with the same content trivially, the virtual machine will also allocate many new memory heaps for it, although their contents are exactly the same. Taking String objects as an example, if 10 String objects with the same content (new String("Hello")) are created continuously, the virtual machine will allocate 10 independent memory heaps for them. Assume that the string content of the created String object is very large. Assume that a Stirng object encapsulates a string content of 1M in size. If we create 10 identical String objects, we will waste 9M of memory space pointlessly. . We know that String is a final class, and what it encapsulates is a string constant. Therefore, the internal (string) value of the String object cannot be changed after it is created, and therefore the String object can be shared. So for the assumption just mentioned, for the 10 String objects we created with the same content, we actually only need to create one String object for this, and then it will be shared by other String variables. To implement this mechanism, the only and simple way is to use the String buffer pool, because there will be no String objects with the same content in the String buffer pool. The intern() method is the way to use this mechanism. After calling the intern() method on an instantiated String object, the virtual machine searches for a String object with the same value as the string content encapsulated by this Stirng object in the String buffer pool, and then assigns the reference to the original String object. String type variable. If there is no String object with the same value as the string content encapsulated by this String object in the String buffer pool, the virtual machine will create a new String object and assign its reference to the String type variable that refers to the original String object. . In this way, the purpose of sharing the same String object is achieved, and the original String object created through the new keyword will be discarded and recycled by the garbage collector. This not only reduces memory usage and improves performance, but also makes it more convenient to compare String objects, because the same String objects will be shared, so to determine whether two String objects are the same, you only need to use " == to compare, instead of using the equals() method to compare. This is not only more convenient to use, but also improves performance, because the equals() method of the String object will disassemble the string content and then process it one by one. Comparison, if the string content is very large, then this comparison action will greatly reduce performance.对 When it comes to this, everyone may be a bit vague about the specific application, so let me give a simple example in order to explain the above concepts:
Assuming that there is a class, it has a method of recording messages. This method records the user comes from the user. message (assuming that the message content may be large and the repetition rate is high), and the messages are recorded in a list in the order in which they are received. I think some friends will design it like this:
import java.util.*;
public class Messages {
ArrayList messages = new ArrayList();
public void record(String msg) {
messages.add(msg );
}
public List getMessages() {
return messages;
}
}
Is this design good? Suppose we repeatedly send the same message to the record() method (the message comes from different users, so each message can be regarded as a new String("...")), and the message content is large, then this design will This is a great waste of memory space, because all records in the message list are newly created, independent String objects, although their contents are the same. So how can we optimize it? It’s actually very simple. Please see the following optimized example:
import java.util.*;
public class Messages {
ArrayList messages = new ArrayList();
public void record(String msg) {
messages.add(msg.intern());
}
public List getMessages() {
return messages;
}
}
As you can see , the original messages.add(msg); code segment in the record() method has become messages.add(msg.intern());, only the intern() method is called for the msg parameter, so that duplicate messages will be Sharing mechanism, thereby reducing memory consumption and improving performance.
This example is indeed a bit far-fetched, but it is just to illustrate the above concept!
At this point, the fog of String objects has been eliminated. As long as you keep these concepts in mind, any complex String application in the future can be analyzed based on this.
For more related articles about how String uses the equals method and == to compare respectively, please pay attention to the PHP Chinese website!