32

我有两个从同一个类实例化的 java 对象。

MyClass myClass1 = new MyClass();
MyClass myClass2 = new MyClass();

如果我将它们的两个属性都设置为完全相同的值,然后验证它们是否相同

if(myClass1 == myClass2){
   // objects match
   ...

}

if(myClass1.equals(myClass2)){
   // objects match
   ...

}

但是,这些方法都没有返回真实值。我检查了每个属性,它们匹配。

如何比较这两个对象以验证它们是否相同?

4

5 回答 5

85

您需要提供自己的equals()in实现MyClass

@Override
public boolean equals(Object other) {
    if (!(other instanceof MyClass)) {
        return false;
    }

    MyClass that = (MyClass) other;

    // Custom equality check here.
    return this.field1.equals(that.field1)
        && this.field2.equals(that.field2);
}

hashCode()如果您的对象有可能在哈希表中使用,您还应该覆盖。一个合理的实现是将对象字段的哈希码与以下内容结合起来:

@Override
public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 37 + this.field1.hashCode();
    hashCode = hashCode * 37 + this.field2.hashCode();

    return hashCode;
}

有关实现散列函数的更多详细信息,请参阅此问题。

于 2013-04-17T20:00:23.067 回答
7

您需要覆盖equalshashCode.
equals将根据您需要的属性比较对象的相等性,并且hashCode是强制性的,以便您的对象正确使用CollectionsMaps

于 2013-04-17T20:00:31.363 回答
6

您需要在MyClass.

==不起作用的原因是检查它们是否引用相同的实例。由于您new对每个都做了,因此每个都是不同的实例。

不起作用的原因equals()是您还没有自己实现它。我相信它的默认行为与==.

请注意,hashcode()如果您要实现,您也应该实现,equals()因为很多 java.util 集合都期望这样做。

于 2013-04-17T20:01:49.340 回答
5

您必须从类 Object 中正确覆盖方法 equals()

编辑:我认为我的第一反应被误解了,可能是因为我不太精确。所以我决定添加更多的解释。

为什么你必须重写equals()?好吧,因为这是在开发人员的领域内决定两个对象相等意味着什么。在大多数情况下,引用相等是不够的。

例如,假设您有一个 HashMap,其键是 Person 类型。每个人都有姓名和地址。现在,您想使用密钥查找详细的 bean。问题是,您通常无法创建具有与地图中的引用相同的引用的实例。您所做的是创建类 Person 的另一个实例。显然,运算符 == 在这里不起作用,您必须使用 equals()。

但是现在,我们遇到了另一个问题。假设您的收藏非常大,并且您想要执行搜索。天真的实现会使用 equals() 将您的关键对象与地图中的每个实例进行比较。然而,这将是非常广泛的。hashCode() 来了。正如其他人指出的那样,哈希码是一个不必唯一的数字。重要的要求是,每当 equals() 为两个对象返回 true 时,hashCode() 必须为这两个对象返回相同的值。反推不成立,这是一件好事,因为哈希码将我们的密钥分成不同的桶。我们在单个存储桶中有少量 Person 类的实例。当我们执行搜索时,算法可以立即跳转到正确的存储桶,现在只对每个实例执行 equals。

还有一点。某些集合需要在用作键的类中正确实现 hashCode() 方法,这不仅是出于性能原因。示例是:HashSet 和 LinkedHashSet。如果它们不覆盖 hashCode(),则默认 Object hashCode() 方法将允许将您可能认为“有意义相等”的多个对象添加到“不允许重复”集合中。

一些使用 hashCode() 的集合

  • 哈希集
  • 链接哈希集
  • 哈希映射

看看 apache commons 中的这两个类,它们可以让你轻松实现 equals() 和 hashCode()

于 2013-04-17T19:59:37.077 回答
2

1) == 在这种情况下评估引用相等
2) 我不太确定相等,但为什么不简单地覆盖比较方法并将其植入 MyClass 中?

于 2013-04-17T20:00:37.753 回答