In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article will explain in detail how to correctly rewrite the equals method in Java. The editor thinks it is very practical, so I share it with you as a reference. I hope you can get something after reading this article.
1. What is the equals method?
First of all, we need to know that the Object class is the parent (superclass / base class) of all classes in Java, that is, in Java, all classes inherit from the Object class by default, in other words, the methods implemented in the Object class can be used directly. The equals method is one of the many methods implemented by the Object class.
The following screenshot is from Java11 API
All methods of the Object class:
1.1 equals method:
Equals: is a method in the Object class, which can only determine the reference type. Later, you can take a look at the jdk source code.
The default judgment is whether the address is equal (because the underlying nature of the reference type variable is to store the address of the object, which should be well known to the partners with the knowledge of Cripple +), this method is often overridden in subclasses to determine whether the contents of the object are equal. For example, you will learn about Integer and String later (see the source code implementation in IDEA)
two。 Why override the equals method?
Why don't we just use the equals method implemented by the Object class? Why rewrite the equals method? It's time to look at the equals method implementation mechanism of the Object class.
We can clearly see that the underlying equals method of the Object class is implemented with = =, which means that its usage is consistent with the = = usage that we normally use to compare basic data types. Let's first take a look at the syntax of = =:
= = can only be used to compare the equality of basic data types, that is, simple value comparison
= = there may also be invalidation when comparing floating-point numbers, because floating-point numbers do not have the same storage mechanism as integer families, and floating-point numbers themselves cannot represent an exact value (for specific reasons, please see the IEEE 754 rule, which is no longer expanded here)
So we can use = = when comparing values of basic data types, while comparing reference data types cannot do so. As mentioned earlier, reference data types are essentially used to reference / store the address of an object, so you can treat it as a pointer to Java.
Note: don't confuse the Java reference with the C++ reference. C++ reference actually refers to the constant, that is, int* const, which is why C++ reference can only be used as an alias for a variable.
2.1 give me an example.
When comparing two int, we can directly use = =, when they are equal, the result is true, but when new has two objects with exactly the same properties, using = = to compare will make an error. As we can see, we should have wanted to get true, but the result is false.
Source code:
Running result:
At this point, we should have a rough idea of why we override the equals method when comparing objects, because the Object class does not work well for us.
3. Analyze the equals source code:
Before rewriting, let's take a look at the definition in Java API:
Public boolean equals (Object obj)
Function: indicates whether some other object is "equal" to this object.
The equals method implements equivalence on non-null object references:
Reflexivity: for any non-empty reference value x, x.equals (x) should return true.
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.
Transitivity: for any non-null reference values x, y, and z, if x.equals (y) returns true y.equals (z) returns true, then x.equals (z) should return true.
Consistency: for any non-null reference values x and y, multiple calls to x.equals (y) always return true or false, as long as the information used in the equals comparison on the object is not modified.
For any non-empty reference value x, x.equals (null) should return false.
The equals method of class Object implements the most distinct possible equivalence on an object; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x = = y has the value true).
Note: you usually need to override the hashCode method when overriding this method in order to maintain the general convention of the hashCode method, which states that equal objects must have equal hash codes.
Next, look at the overridden equals method in the String class and the overridden equals method in the Integer class:
/ / String class equals source code: public boolean equals (Object anObject) {if (this = = anObject) {return true;} if (anObject instanceof String) {String anotherString = (String) anObject; int n = value.length; if (n = = anotherString.value.length) {char v1 [] = value Char v2 [] = anotherString.value; int I = 0; while (NMI -! = 0) {if (v1 [I]! = v2 [I]) return false; iTunes;} return true }} return false;}
A simple interpretation is that when the comparison is the same object, directly return true to improve efficiency. When the incoming object is an instance of the current class, a for loop iterates through each character of the string in turn, returning false as long as one character is different.
Let's take a look at the equals source code for the Integer class:
/ / equals source code for the Integer class: public boolean equals (Object obj) {if (obj instanceof Integer) {return value = = ((Integer) obj) .intValue ();} return false;}
The equals source code of the Integer class is much simpler. As long as the object passed in is an instance of the current class, further judgment is made: when their values are equal, they return true, and if they are not equal, they return false.
Here's a practical demonstration of ⑧, taking the Integer class as an example:
Obviously, we know that the Integer class overrides the equals method and is a reference type. When comparing reference type variables directly with = =, the result is false, while the result is judged to be true with equals. This is a good illustration of the need to rewrite the equals method. Everyone in the String category verifies a ⑧ by themselves.
4. Correctly override the equals method:
(first of all, getClass () is more secure than instanceof.)
At this point, we have basically analyzed the various sources of the equals method, and then it is time for us to implement the equals method ourselves.
Here are two common equals rewriting methods:
Implementation of rewriting equals method with instanceof
Implementation of rewriting equals method with getClass
Suppose you have this scenario:
Override the equals method in the Object class in the created rectangle class to return TRUE when the length and width of the rectangle are equal, override the hashCode method, and rewrite the toString method to display the length and width information of the rectangle. And test the class.
Package com.test10_04;import java.util.Objects;class Rectangle {private double length; private double wide; public Rectangle () {/ / empty implementation} public Rectangle (double length, double wide) {setLength (length); setWide (wide);} public double getLength () {return length } public void setLength (double length) {assert length > 0.0: "your input is incorrect, the length of the rectangle cannot be less than 0"; this.length = length;} public double getWide () {return wide;} public void setWide (double wide) {assert wide > 0.0: "your input is incorrect, the width of the rectangle cannot be less than 0"; this.wide = wide } public double area () {return this.length * this.wide;} public double circumference () {return 2 * (this.wide + this.length);} public boolean equals (Object obj) {if (this = = obj) {/ / judge if the same object is returned directly to true to improve efficiency return true } if (obj = = null | | obj.getClass ()! = this.getClass ()) {/ / if the incoming object is null or the two are of different classes, return false return false directly } / / you can also use the following methods: / / if (obj = = null | |! (obj instanceof Rectangle)) {/ / if the incoming object is null or the two are of different classes, directly return false// return false;//} Rectangle rectangle = (Rectangle) obj / / Down transition / / compare whether the length and width are equal. Note: the comparison of floating point numbers cannot simply use = =. There will be an error of accuracy. Use Math.abs or Double.compare return Double.compare (rectangle.length, length) = = 0 & & Double.compare (rectangle.wide, wide) = = 0 } public int hashCode () {/ / override hashCode while overriding equals, because hashCode of the same object is always equal to return Objects.hash (length, wide); / / call the Objects class, which is a subclass of the Object class} public String toString () {return "Rectangle {" + "length=" + length + ", wide=" + wide +'}' }} public class TestDemo {public static void main (String [] args) {Rectangle rectangle1 = new Rectangle (3.0,2.0); Rectangle rectangle2 = new Rectangle (3.0,2.0); System.out.println (rectangle1.equals (rectangle2)); System.out.println ("rectangle1 hash code:" + rectangle1.hashCode () + "\ nrectangle2 hash code:" + rectangle2.hashCode ()) System.out.println ("toString print message:" + rectangle1.toString ());}}
The specific implementation idea is very clear in the code. Here we focus on analyzing the advantages and disadvantages of getClass and instanceof implementation methods:
Simplify the logic of the code:
Let's focus on this simple code.
/ / getClass () version public class Student {private String name; public void setName (String name) {this.name = name;} @ Override public boolean equals (Object object) {if (object = = this) return true / / use getClass () to determine whether an object belongs to this class if (object = = null | | object.getClass ()! = getClass ()) return false; Student student = (Student) object; return name! = null & & name.equals (student.name);} / / instanceof version public class Student {private String name Public void setName (String name) {this.name = name;} @ Override public boolean equals (Object object) {if (object = = this) return true / / use instanceof to determine whether the object belongs to class if (object = = null | |! (object instanceof Student)) return false; Student student = (Student) object; return nameplate null & name.equals (student.name);}}
In fact, both schemes are effective. The difference is that getClass () restricts the object to be the same class, while instanceof allows the object to be the same class or its subclass, so the equals method becomes a parent class and a subclass can also perform equals operations. At this time, if the subclass redefines the equals method, it may become the parent object equlas subclass object is true, but the subclass object equlas parent object is false, as shown below:
Class GoodStudent extends Student {@ Override public boolean equals (Object object) {return false;} public static void main (String [] args) {GoodStudent son = new GoodStudent (); Student father = new Student (); son.setName ("test"); father.setName ("test"); / / System.out.println (son.equals (father) when using instance of) / / false System.out.println (father.equals (son)); / / true / / System.out.println (son.equals (father)) when using getClass (); / / false System.out.println (father.equals (son)); / / false}}
Notice that getClass () is used here.
The return values are both false, which is in line with our expectations. (even if the class is different, it must be false.)
Try instanceof instead:
Run result: one is true and the other is false. Obviously, there is a problem.
The reasons are as follows:
The syntax of instanceof is as follows:
The result is true when an object is an instance of a class. But it also has a feature that if this object is an instance of its subclass, the result will also be true. This leads to the above bug. In other words, instanceof may have problems when comparing two objects whose classes are parent-child relationships. * * partners who need to study deeply can learn about it for themselves, so it is recommended to use getClass as far as possible when implementing the overridden equals method.
You need to override the equals method as well as the hashCode method.
This is the end of the article on "how to correctly rewrite the equals method in Java". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.