One of the most common operations in programming is to determine whether two things are equal. In Java, there are two ways to determine whether something is equal. One is to use the equals() method, and the other is to use the equals() method. This article will take you through the reasoning behind both.
Equality judge “==”
The “==” equality judgment is used to compare basic data types with reference type data. Values are compared when comparing basic data types, and references (Pointers) are compared when comparing reference data types.
“==” Determines base type data
The basic data types refer to the eight data types in Java: byte, short, int, long, float, double, char, Boolean
The common feature of these eight basic data types is that they have specific values in memory. For example, an int of type “2” is stored as 0000 0010 on an 8-bit data bus machine. (8-bit machine is assumed)
When you compare two basic data types using ==, you are comparing their respective values in memory.
For those of you who want to know, how the two values are compared: the CPU compares the two values and then looks at the flag register. The flag register contains the result of the operation, and there is a flag bit which is 0 or not. If the flag bit is 1, the difference between the two is 0 and the two are equal.
“==” determines the reference type data
A reference data type is also quite literal; it is just a reference to a concrete object in the heap.
Student stu = new Student(); Stu here is just a reference to the Student object that’s out of the current new. When we want to manipulate the Student object, we just need to manipulate the reference, such as int age = stu.getage (); .
So when we use “==” to determine whether two reference data types are equal, we are actually determining whether two references refer to the same object.
Look at the following example:
public static void main(String[] args) {
String s1 = "hello"; //s1 points to the "hello" string object in the string constant pool
String s2 = "hello"; S2 also points to the "hello" string object in the string constant pool
System.out.println(s1 == s2); //true
String s3 = new String("hello"); //s3 refers to a string object in the heap
System.out.println(s1 == s3); //false
}
Copy the code
As you can see from the above example, the reference “s1” and “s2” both refer to the “hello” string in the constant pool, so return true. (I’ll post a more detailed article on Java strings later, covering things like string initialization and string constant pools.)
And “s3” refers to the newly created string object, because whenever the new keyword is used, a new object is created in the heap.
That is, s1 and S3 refer to different string objects, so return false.
Equals ()
Equals () is fundamentally different from equals(), which can be seen as an encapsulation of the operating system’s way of comparing data), whereas equals() is the built-in comparison method for each object, which is a custom comparison rule for Java.
The essential difference between equals() and == is more commonly referred to as the “fixed” comparison rule, which compares two data values.
The equals() comparison rules are not fixed and can be defined by the user.
Look at the following example:
public static void main(String[] args) {
String s1 = "hello";
String s3 = new String("hello");
System.out.println(s1.equals(s3)); //true
}
Copy the code
Recall from the previous example: when s1 and S3 were compared with ==, the above results were false. When using equals(), the result is true.
To see why, we have to look at the source code. Here is the source code for the equals() method in the String class.
public boolean equals(Object anObject) {
if (this == anObject) { // Compare references to two strings for equality, and return true if they refer to the same object
return true;
}
if (anObject instanceof String) { // The two references will continue to be compared
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value; // The string class is implemented with a character array. First, we need to get the character array of two strings
char v2[] = anotherString.value;
int i = 0;
while(n-- ! =0) { // Then compare the two arrays character by character
if(v1[i] ! = v2[i])return false;
i++;
}
return true; }}return false;
}
Copy the code
As you can see from the source code above, when calling the equals() method for String data, it first determines whether the two String references are equal, that is, whether the two String references refer to the same object. If so, it returns true.
If it does not point to the same object, the characters in both strings are compared one by one. Since the s1 and S3 strings are both “hello” and can be matched, true is finally returned.
Consider: Why design the equals() method?
You already know the difference between equals() and equals() : one is fixed, and the other is defined by the programmer.
So why is there an equals() method that can be customizable?
This goes to the heart of the Java language — object-oriented thinking.
Unlike procedural C language, Java is a high-level object-oriented language. For procedural programming that directly manipulates data stored in memory, the rule defined by == is sufficient to determine whether two pieces of data are equal.
In Java, everything is an object, and the question we often face is whether the two objects are equal, not whether the two strings of binary numbers are equal. Just == is not enough.
Since Java programmers create various objects that meet their business needs, the system has no way of knowing in advance when two objects are equal, and Java simply leaves it up to the programmer to determine whether an object is equal.
To do this, all classes must inherit from the Object class, which has the equals() method. Programmers can implement their own comparison strategy by overriding the equals() method, or by not overriding it and using the Object class’s equals() comparison strategy.
// The equals() method in the Object class source code
public boolean equals(Object obj) {
return (this == obj);
}
Copy the code
As you can see from the equals() source code for the Object class, if the programmer does not explicitly override the equals() method, the default is to compare whether two references refer to the same Object.
Addendum: Comparison of wrapper classes for basic data types
Since everything in Java is an object, even basic data types have their wrapper classes, so what’s the comparison strategy?
public static void main(String[] args) {
int a = 3;
Integer b = new Integer(3);
System.out.println(b.equals(a)); // True, automatic boxing
}
Copy the code
As you can see from the above code, the output is true despite the two different references, proving that the Integer wrapper class overwrites the equals() method and traces its source code:
// The equals method in the Integer class
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
Copy the code
As you can see from the source code, after overriding equals(), the base type wrapper class still compares the values of the base data type.
The end of the
By exploring the difference between equals() and equals(), we find out the comparison strategy after the two, and at the same time, we also think about the design of equals() method in Java. We believe that we will not worry about the equality judgment in the future Java programming practice.