equals()
There is this equals() method in the super class Object. This method is mainly used to compare whether two objects are equal. The source code of this method is as follows:
public boolean equals(Object obj) { return (this == obj); }
We know that all objects have identification (memory address) and status (data). At the same time, "==" compares the memory addresses of two objects, so we use Object The equals() method compares whether the memory addresses of two objects are equal. That is, if object1.equals(object2) is true, it means equals1 and equals2 actually refer to the same object. Although sometimes the equals() method of Object can meet some of our basic requirements, we must be aware that most of the time we compare two objects. At this time, the equals() method of Object cannot be used. In fact, In the previous JDK, encapsulation classes such as String and Math have rewritten the equals() method.
The following is the equals() method of String:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
For this code segment: if (v1[i++] != v2[j++]) return false; we can see very clearly String's equals() method performs content comparison, not reference comparison. As for other encapsulation classes, they are similar.
In the Java specification, its use of the equals() method must follow the following rules:
The equals method is on a non-null object reference Realizing equality:
1. Reflexivity: For any non-null reference value x, x.equals(x) should return true.
2. Symmetry: For any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
3. Transitivity: For any non-null reference values x, y and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) Should return true.
4. Consistency: For any non-null reference values x and y, calling x.equals(y) multiple times will always return true or always return false, provided that the information used in the equals comparison on the object has not been Revise.
5. For any non-null reference value x, x.equals(null) should return false.
For the above rules, we'd better abide by them during use, otherwise unexpected errors will occur.
To compare in java, we need to choose the appropriate comparison method according to the type of comparison:
1) In the object field, use the equals method.
2) Type-safe enumeration, use equals or ==.
3) Possibly null object fields: use == and equals.
4) Array field: use Arrays.equals.
5) Primitive data types except float and double: use ==.
6) Float type: Use Float.foatToIntBits to convert to int type, and then use ==.
7) Double type: Use Double.doubleToLongBit to convert to long type, and then use ==.
As for why 6) and 7) need to be converted, we can refer to the equals() method of their corresponding encapsulation class. The following is the Float class:
public boolean equals(Object obj) { return (obj instanceof Float) && (floatToIntBits(((Float)obj).value) == floatToIntBits(value)); }
The reason is that two points are mentioned:
However, there are two exceptions:If f1 and f2 both representFloat.NaN, then the equals method returnstrue, even though Float.NaN==Float.NaNhas the value false.If <code>f1 represents +0.0f whilef2 represents -0.0f, or vice versa, the equal test has the valuefalse, even though 0.0f==-0.0f has the value true.
Use getClass in equals() for type judgment
When we override the equals() method, we generally It is recommended to use getClass for type judgment instead of instanceof. We all know that the function of instanceof is to determine whether the object on the left is an instance of the class on the right and return boolean type data. It can be used to determine whether the instance of the subclass in inheritance is the implementation of the parent class. Pay attention to the following sentence: It can be used to determine whether the instance of the subclass in inheritance is the implementation of the parent class. It is this sentence that is causing trouble. Let's first look at the following example (excerpted from "High-Quality Code: 151 Suggestions for Improving Java Programs").
Parent class: Person
public class Person { protected String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Person(String name){ this.name = name; } public boolean equals(Object object){ if(object instanceof Person){ Person p = (Person) object; if(p.getName() == null || name == null){ return false; } else{ return name.equalsIgnoreCase(p.getName()); } } return false; } }
Subclass: Employee
public class Employee extends Person{ private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } public Employee(String name,int id){ super(name); this.id = id; } /** * 重写equals()方法 */ public boolean equals(Object object){ if(object instanceof Employee){ Employee e = (Employee) object; return super.equals(object) && e.getId() == id; } return false; } }
Both the parent class Person and the subclass Employee above rewrite equals(), but there are more Employee than the parent class An id attribute. The test program is as follows:
public class Test { public static void main(String[] args) { Employee e1 = new Employee("chenssy", 23); Employee e2 = new Employee("chenssy", 24); Person p1 = new Person("chenssy"); System.out.println(p1.equals(e1)); System.out.println(p1.equals(e2)); System.out.println(e1.equals(e2)); } }
The above defines two employees and an ordinary person. Although they have the same name, they are definitely not the same person, so logically the output results should all be false, but contrary to expectations, the result is : true, true, false.
It is very easy for us to understand that e1!=e2, because they not only need to compare names, but also need to compare ids. But p1 is equal to both e1 and e2. This is very strange, because e1 and e2 are obviously two different classes, but why does this happen? First, p1.equals(e1) calls the equals method of p1. This method uses the instanceof keyword to check whether e1 is a Person class. Here we look at instanceof: to determine whether the object on the left is an instance of the class on the right. You can also Used to determine whether the instance of the subclass in inheritance is the implementation of the parent class. There is an inheritance relationship between them, so they will definitely return true, and their names are the same, so the result will definitely be true.
#So the above situation occurs because the keyword instanceof is used, which is very easy to "exploit". Therefore, it is recommended to use getClass for type judgment when overriding equals. Instead use instanceof.
The above is the summary of the Java improvement article----equals() method. For more related content, please pay attention to the PHP Chinese website (m.sbmmt.com)!