Equals() 方法帮助

3

我需要为团队类编写一个equals()方法,该方法与提供的hashCode()方法一致

hashCode()方法:

 public int hashCode()
   {
      return this.getPro().hashCode() 
             + this.getTeam().hashCode(); 
   }

我的equals方法不起作用

public boolean equals(Object obj)
   {
     ClassName pro = (ClassName) obj;
     return (this.getPro().hashCode() == pro.getPro());
             (this.getTeam().hashCode() == pro.getTeam());
   }

任何帮助都会很好


1
你正在将哈希码与对象进行比较,这是行不通的。你想要实现什么?你认为hashCode()方法是做什么用的? - Kirk Woll
如果您要将对象放入HashSet或HashMap中,则相等的两个对象必须返回相同的hashCode,而返回不同hashCode的两个对象则不能相等。两个不相等的对象可以返回相同的hashCode(例如,有40亿个可能的hashCode,但是字符串的可能性更多)。您不能根据hashCode()定义equals();它可能会将两个不相等的对象视为相等。 - Mark Lutton
2个回答

3
在这里,你将哈希码(一个整数)与对象进行比较。此外,在语句中间有一个分号。
相反,你应该尝试这样做:
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    MyClass myClass = (MyClass) o;

    if (!pro.equals(myClass.pro)) return false;
    if (!team.equals(myClass.team)) return false;

    return true;
}

这里是对对象内容进行比较的地方。
在@Bart K.的评论之后,如果team或pro可以为空,则写equals()方法的方式如下:
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    MyClass myClass = (MyClass) o;

    if (pro != null ? !pro.equals(myClass.pro) : myClass.pro != null) return false;
    if (team != null ? !team.equals(myClass.team) : myClass.team != null) return false;

    return true;
}

资源:

同一主题:


equals(...) 应该同时检查 obj == null - Bart Kiers
这取决于“pro”和“team”是否可为空。由于它们似乎不可为空(参见OP的hashCode()),因此这并不是真正必要的。 - Colin Hebert
不,我并不是指 proteam 为空,而是 obj。例如,一个 ArrayList<ClassName> 可以包含 null 引用,如果你在其中执行 contains(instanceOfClassName) 操作,你的实现会在将 nullthis 进行比较时抛出 NPE 异常。 - Bart Kiers
我的错,你是对的,我用更好的等于方法编辑了代码。 - Colin Hebert
点赞不在方法调用前加上this - Steve Kuo

2
  1. 两个对象的哈希值相等并不意味着这两个对象相等。
  2. 要检查两个条件是否都满足,使用 &&

因此,

public boolean equals(Object obj)
   {
     ClassName pro = (ClassName) obj;
     return this.getPro() == pro.getPro() && this.getTeam() == pro.getTeam();
   }

然而,你的hashCode()方法可能无法生成好的哈希值,而equals()方法在许多情况下也会失败(例如与非ClassNamenull进行比较)。请参见Java中重写equals和hashCode方法以了解如何正确实现它们。假设没有派生类,请尝试以下方法:

@Override public boolean equals(Object obj) {
   if (obj == this) return true;
   if (!(obj instanceof ClassName)) return false;
   ClassName pro = (ClassName)obj;
   <sometype> thisPro = getPro();
   if (thisPro == null || !thisPro.equals(pro.getPro()) return false;
   <sometype> thisTeam = getTeam();
   if (thisTeam == null || !thisTeam.equals(pro.getTeam()) return false;
   return true;
}

2
我不会在equals()方法中使用==来比较对象。大多数情况下(如果不是全部),如果对象的内容相等,则对象本身也相等。 - Colin Hebert
条件(obj == null)是多余的:(null instanceof ClassName)== false。 - meriton
@Colin:糟糕,我假设==比较的是值而不是引用。已修复。 - kennytm
“等于”意味着什么完全取决于你想要做什么。例如,您可能完全基于ID字段而不考虑任何其他内容来确定相等性。通常,如果两个对象都模拟相同的概念(例如6/8等于3/4(除了音乐))或相同的现实世界对象,则它们是相等的。如果您有两个对象,并且将两者都放入HashSet中,并且您希望集合仅包含其中一个并且您不关心哪个,则这两个对象是相等的。 - Mark Lutton

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