2013-04-17 150 views
25

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

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

如果我同时设置其属性的完全相同的值,然后验证它们是相同的

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

} 

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

} 

然而,这些方法都不返回真值。我已经检查过每一个的属性,他们匹配。

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

+0

我做了谷歌,但我发现所有的例子从来没有解释,你不得不重写equals方法。 –

+0

@AndroidAddict:那你为什么不问这个问题? – 2013-04-17 20:18:01

回答

71

您需要提供自己实现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); 
} 

你也应该重写hashCode()如果有在哈希表中正在使用你的对象的任何机会。一个reasonable implementation是将对象的字段的哈希码的东西,如结合:

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

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

    return hashCode; 
} 

上实现的哈希函数的详细信息,请参阅this question

+1

为什么37?素数? – Aubin

+1

@Aubin通常情况下,素数在哈希代码生成使用。如果我没有记错的话,它减少的机会,将有上生成散列碰撞。至于为什么要用37,我想这只是一个流行的选择,我不知道有什么特别的原因,使用37而不是说,13 – afsantos

+0

谢谢 - 一切真的。每个人都把我放在正确的道路上,但我只能接受一个正确的道路。 –

5

你必须正确地重写方法equals()方法从Object类

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

为什么你必须重写equals()?那么,因为这是一个开发人员决定两个对象是否相等意味着什么的领域。大多数情况下参考平等是不够的。

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

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

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

一些使用的hashCode()

  • HashSet的藏品
  • LinkedHashSet
  • HashMap的

看一看Apache的公地这两个类,可以让你实现等于()和hashCode()容易

7

你需要重写equalshashCode
equals将根据需要和hashCode是强制性为了要在Collections正确使用和你的对象的属性比较对象是否相等Maps

2

1)==评估基准平等在这种情况下
2)即时通讯不太清楚等于什么,但为什么不简单地重写比较方法并将其植入MyClass?

5

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

之所以==没有工作,这是检查它们指的是同一个实例。既然你为每个做了new,每一个都是不同的实例。

之所以equals()没有工作是因为你没有自己实现它。我相信它的默认行为与==是一样的。

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

+0

找到很好的解释。简明扼要。 – tommyO