为什么在Java中我们需要重写equals()方法?

19
我对于为什么要重写.equals方法有些困惑。
例如:
Test test1 = new Test(3);
Test test2 = new Test(3);

//The if comparison does the same thing that the overridden `.equals()` method does.
if(test1.equals(test2)){
    System.out.println("test1 and test2 are true in .equals()");
}

// Override .equals method.
public boolean equals(Object object) {
    if(object instanceof Test && ((Test)object).getValue() == this.t) {
        return true;
    } else {
        return false;
    }
}

我不明白为什么我们需要重写.equals()方法。


1
如果您不重写 test1.equals(test2),它将无法按照您的预期工作。 - Bhesh Gurung
6
注意:如果你重写了equals()方法,就必须同时重写hashCode()方法。 - exexzian
8个回答

45

来自文章在Java中重写equals和hashCode:

java.lang.Object提供的equals()类的默认实现比较内存位置,并且只有当两个引用变量指向相同的内存位置时才返回true,即它们本质上是相同的对象。

如果等价性是通过逻辑方式或某些业务逻辑定义的,则Java建议重写equals和hashCode方法,例如:

Java标准库中的许多类都进行了覆盖,例如String覆盖了equals,其equals()方法的实现会在两个String对象的内容完全相同时返回true

Integer包装类覆盖了equals以执行数字比较等。


21
这应该足以回答你的问题: http://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html

equals() 方法用于比较两个对象是否相等,如果相等则返回 true。在 Object 类中提供的 equals() 方法使用身份运算符(==)来确定两个对象是否相等。对于基本数据类型,这可以得出正确的结果。但是对于对象来说,不是这样的。由 Object 提供的 equals() 方法测试对象引用是否相等,也就是说,如果比较的对象是完全相同的对象,则它们相等。

要测试两个对象是否在等效性意义下相等(包含相同的信息),必须重写 equals() 方法。

(部分引用 - 点击链接查看示例。)


Object类提供的equals()方法使用身份运算符(==)来确定两个对象是否相等。对于基本数据类型,这可以得到正确的结果。然而,对于对象,它不适用。这意味着,如果我们没有发现需要覆盖equals()方法的需求,最好选择使用==。我的理解是正确的吗? - Siva Tumma

6

3

java.lang.Object的默认行为是比较引用,但这并不适用于每种对象。有一些被称为值对象(如BigDecimal或String),其中具有相同值的对象被视为可互换,因此默认的equals行为是不可取的。这些类型的对象必须根据对象所采用的值实现equals和hashcode。


2

默认情况下,.equals() 使用 == 身份函数进行比较,显然这不起作用,因为实例 test1 和 test2 不相同。== 仅适用于原始数据类型,如 int 或 string。因此,您需要覆盖它以通过比较 Test 类的所有成员变量使其起作用。


当创建一个类并且需要进行比较时,覆盖equals方法被认为是一种良好的实践。 - user1559897

2
让我给你举一个我认为非常有用的例子。
您可以把引用看作是书页的页码。现在假设您有两个页面a和b,如下所示。
BookPage a = getSecondPage(); BookPage b = getThirdPage();
在这种情况下,a == b将会返回false。但是为什么呢?原因是==比较的是页码。因此,即使这两个页面上的内容完全相同,您仍然会得到false。
但是我们如果想要比较内容怎么办呢?
答案是编写自己的equals方法,并指定您真正想要比较的内容。

2
回答你的问题,首先我强烈建议查看文档
如果不覆盖equals()方法,它将像“==”一样运作。当您在对象上使用“==”运算符时,它仅检查这些指针是否引用相同的对象,而非它们的成员是否包含相同的值。
我们覆盖equals()方法是为了保持代码清晰,并将比较逻辑从if语句中抽象出来,并放入对象中。这被认为是良好的做法,并利用了Java的面向对象的优势。

1

Object.equals()方法仅检查对象的引用,而不是基本数据类型或对象值(基本数据类型的包装类对象、简单的基本数据类型(byte、short、int、long等))。因此,当我们基于基本数据类型比较对象时,必须重写equals()方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接