如何比较两个java对象

Roy*_*ley 29 java compare object

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

MyClass myClass1 = new MyClass();
MyClass myClass2 = new MyClass();
Run Code Online (Sandbox Code Playgroud)

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

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

}

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

}
Run Code Online (Sandbox Code Playgroud)

但是,这些方法都没有返回真正的价值.我检查了每个属性并匹配.

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

Joh*_*ica 79

您需要提供自己实现equals()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);
}
Run Code Online (Sandbox Code Playgroud)

hashCode()如果您的对象有可能在哈希表中使用,您还应该覆盖.一个合理的实施将是该对象的字段的哈希码喜欢的东西结合起来:

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

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

    return hashCode;
}
Run Code Online (Sandbox Code Playgroud)

有关实现哈希函数的更多详细信息,请参阅此问题.


Cra*_*lus 7

你需要覆盖equalshashCode.
equals将根据您需要的属性比较对象的相等性,并且hashCode是必需的,以便在Collections和中正确使用对象Maps


rar*_*rry 5

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

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

你为什么要重写equals()?好吧,因为这是在开发人员的领域,以决定两个对象是平等的意义.对于大多数情况,参考平等是不够的.

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

但现在,我们遇到了另一个问题.让我们假设您的集合非常大,并且您想要执行搜索.天真的实现会使用equals()将您的关键对象与地图中的每个实例进行比较.然而,这将是非常广泛的.这里是hashCode().正如其他人所指出的,哈希码是一个不必唯一的数字.重要的要求是,只要equals()为两个对象赋予true,hashCode()必须为它们返回相同的值.反过来的含义并不成立,这是一件好事,因为hashcode将我们的密钥分成了一种桶.我们在一个存储桶中有少量类Person的实例.当我们执行搜索时,算法可以立即跳转到正确的存储桶,现在只为每个实例执行equals.因此,hashCode()的实现必须在桶之间尽可能均匀地分布对象.

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

一些使用hashCode()的集合

  • HashSet的
  • LinkedHashSet
  • HashMap中

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


Dan*_*lan 5

你需要在你的实现equals()方法MyClass.

==不起作用的原因是检查它们是否引用相同的实例.由于你new为每个人做了,每个人都是一个不同的实例.

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

请注意,hashcode()如果您要实现,也应该实现,equals()因为很多java.util Collections都希望如此.