How to correctly override the equals method in Java
1. What is the equals method?
We must first know that the Object class
is the parent class (super class/base class) of all classes in Java
, that is to say, in Java In
, all classes inherit from Object class
by default. In other words, we can use all the methods implemented in Object class
directly. The equals
method is one of the many methods implemented by the Object class
.
The following screenshots are taken from Java11 API
All methods of the Object class:
1.1 equals method:
equals
: It is a method inObject class
. It can only determine the reference type. You can bring it later. Everyone, take a look at thejdk
source codeThe default judgment is whether the addresses are equal (because the underlying essence of reference type variables is to store object addresses, those with C/C knowledge Friends should know it very well), this method is often overridden in subclasses to determine whether the contents of objects are equal. For example,
Integer
andString
, which you will learn briefly later (see the source code implementation in IDEA)
2. Why should we rewrite equals method?
We have the Object class
and the equals
method can be used, right? Why do we have to override the equals
method? This depends on the implementation mechanism of the equals
method of the Object class
.
We can clearly see that the bottom layer of the equals
method of the Object class
is implemented using ==, that is It is said that its usage is consistent with the usage of == which we usually use to compare basic data types. Let’s first take a look at the syntax of ==:
== can only be used to compare basic data types for equality, that is, simple value comparison;
== There may also be failures when comparing floating point numbers. This is because the storage mechanism of floating point numbers is different from that of the integer family. The floating point number itself cannot represent an accurate value (you can check the specific reasons by yourself). IEEE 754 rules, will not be expanded here)
So we can use == when simply comparing values of basic data types, but we cannot do this when comparing reference data types, as mentioned above It has been mentioned that the reference data type is essentially used to reference/store the address of the object, so you can treat it as a pointer to C/C
(here it is said that Java does not have pointers, personally I think it’s just a different name)
Note: Don’t confuse the Java
reference with the C
reference. The C reference is actually a pointer constant, that is, int* const
, this is why the reference of C
can only be used as an alias of a variable.
2.1 For example~
When comparing two ints, you can directly use ==. When they are equal, the result is true
, and when new
When two objects with exactly the same attributes are obtained, an error will occur if ==
is used for comparison. As we can see, we should obviously want to get true
, The result is false
Source code:
Running result:
Go here , we should have a rough idea of why we need to override the equals
method when comparing objects, because the Object class
provides us with something that is not easy to use~~
3. Analyze the equals source code:
Before rewriting, let’s still 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-null reference value
x
,x.equals(x)
should returntrue
.Symmetry: For any non-null reference values
x
andy
,x.equals(y)
should returntrue
if and only ify.equals(x)
returnstrue
.Transitivity: For any non-null reference values
x
,y
andz
, ifx. equals(y)
returnstrue
y.equals(z)
returnstrue
, thenx.equals(z)
Should returntrue
.Consistency: Multiple calls to
x.equals(y)
always return for any non-null reference values x
andy
true
Or always returnfalse
, provided that the information used in theequals
comparison on the object has not been modified.For any non-null reference value
x
,x.equals(null)
should returnfalse
.
The equals method of class Object implements the most distinctive possible equivalence relationship on the object; that is, for any non-null reference values x and y, if and only if x and This method returns true when y refers to the same object (x == y has value true).
Note: It is usually necessary to override the hashCode method when overriding this method in order to maintain the normal contract of the hashCode
method, which states that equal objects must have equal hash codes.
Next look at the equals
method overridden in the String class
and the overridden Integer
class The equals
method written:
//String类equals源代码: 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 (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
A simple explanation is that when the comparison is the same object, it directly returns true
, Improve efficiency. When the object passed in is an instance of the current class, further judgment is entered. A for
loop traverses each character of the string in turn, and returns false
as long as one character is different.
Continue to take a look at the equals
source code of the Integer
class:
//Integer类的equals源代码: public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
Integer class
's equals
source code is much simpler. As long as the incoming object is an instance of the current class, further judgment will be made: when their values are equal, true
will be returned, otherwise If equal, return false
.
Let’s give a practical demonstration ⑧, taking the Integer class
as an example:
Obviously, we know Integer class
overrides the equals
method and is a reference type. When == is directly used to compare reference type variables, the result is false
, and equals
is used to determine the result is true
. This well illustrates the necessity of overriding the equals
method. String class
Please verify it yourself⑧.
4. Correctly rewrite the equals method:
(Let me talk about the conclusion first, getClass()
is safer than instanceof
)
At this point, we have basically analyzed the various source codes of the equals
method. The next step is to implement the equals
method ourselves.
Here are two common equals
rewriting methods:
Use
instanceof
to implement rewritingequals
methodUse
getClass
to implement overridingequals
method
Assume there are This scenario:
Override the equals
method in the Objec
t class in the already created rectangle class to return # when the length and width of the rectangle are equal. ##TRUE, while overriding the
hashCode method, and overriding 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() { //空实现 } public Rectangle(double length, double wide) { setLength(length); setWide(wide); } public double getLength() { return length; } public void setLength(double length) { assert length > 0.0 : "您的输入有误,长方形的长不能小于0"; this.length = length; } public double getWide() { return wide; } public void setWide(double wide) { assert wide > 0.0 : "您的输入有误,长方形的宽不能小于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) { //判断一下如果是同一个对象直接返回true,提高效率 return true; } if (obj == null || obj.getClass() != this.getClass()) { //如果传进来的对象为null或者二者为不同类,直接返回false return false; } //也可以以下方法: // if (obj == null || !(obj instanceof Rectangle)) { //如果传进来的对象为null或者二者为不同类,直接返回false // return false; // } Rectangle rectangle = (Rectangle) obj; //向下转型 //比较长宽是否相等,注意:浮点数的比较不能简单地用==,会有精度的误差,用Math.abs或者Double.compare return Double.compare(rectangle.length, length) == 0 && Double.compare(rectangle.wide, wide) == 0; } public int hashCode() { //重写equals的同时也要重写hashCode,因为同一对象的hashCode永远相等 return Objects.hash(length, wide); //调用Objects类,这是Object类的子类 } 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哈希码:" + rectangle1.hashCode() + "\nrectangle2哈希码:" + rectangle2.hashCode()); System.out.println("toString打印信息:" + rectangle1.toString()); } }
getClass and
instanceof:
Let’s focus on this simple code
//getClass()版本 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; // 使用getClass()判断对象是否属于该类 if (object == null || object.getClass() != getClass()) return false; Student student = (Student)object; return name != null && name.equals(student.name); }
//instanceof版本 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; // 通过instanceof来判断对象是否属于类 if (object == null || !(object instanceof Student)) return false; Student student = (Student)object; return name!=null && name.equals(student.name); } }
getClass() restricts the object to be the same class, but
instanceof allows the object to be the same class or its subclass, so the equals method becomes the parent class and subclass The equals operation can also be performed. At this time, if the subclass redefines the equals method, it may become the parent class object equlas. The subclass object is true, but the subclass object equlas the parent class 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"); // 当使用instance of时 System.out.println(son.equals(father)); // 这里为false System.out.println(father.equals(son)); // 这里为true // 当使用getClass()时 System.out.println(son.equals(father)); // 这里为false System.out.println(father.equals(son)); // 这里为false } }
getClass() is used here
false , in line with our expectations, (even if the class is different, it must be
false)
instanceof Give it a try:
Running results: One is true
and the other is false
, obviously there is a problem.
The reasons here are as follows: The syntax of instanceof
is like this:
When an object is an instance of a class, the result Only then is true
. But it also has a characteristic that if this object is an instance of its subclass, the result will also be true
. This leads to the above bug. That is to say, when the two objects being compared have a parent-child relationship, instanceof
may cause problems. **Friends who need to learn more can learn it by themselves, so it is recommended that when rewriting the equals
method, try to use getClass
to achieve it.
When rewriting the equals
method, you need to override the hashCode
method.
The above is the detailed content of How to correctly override the equals method in Java. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Guide to Perfect Number in Java. Here we discuss the Definition, How to check Perfect number in Java?, examples with code implementation.

Guide to Weka in Java. Here we discuss the Introduction, how to use weka java, the type of platform, and advantages with examples.

Guide to Smith Number in Java. Here we discuss the Definition, How to check smith number in Java? example with code implementation.

In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

Guide to TimeStamp to Date in Java. Here we also discuss the introduction and how to convert timestamp to date in java along with examples.

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

Java is a popular programming language that can be learned by both beginners and experienced developers. This tutorial starts with basic concepts and progresses through advanced topics. After installing the Java Development Kit, you can practice programming by creating a simple "Hello, World!" program. After you understand the code, use the command prompt to compile and run the program, and "Hello, World!" will be output on the console. Learning Java starts your programming journey, and as your mastery deepens, you can create more complex applications.
