java - equals 和 hashCode : Is Objects. 哈希方法坏了?

标签 java equals hashcode

我正在使用 Java 7,下面有以下类。我正确地实现了 equalshashCode,但问题是 equals 在下面的主要方法中返回 false hashCode 为两个对象返回相同的哈希代码。我可以让更多的眼睛看这个类,看看我在这里做错了什么吗?

更新: 我用自己的哈希函数替换了调用 Objects.hash 方法的行:chamorro.hashCode() + english.hashCode () + notes.hashCode().它返回一个不同的散列码,这是当两个对象不同时 hashCode 应该做的。 Objects.hash 方法是否损坏?

非常感谢您的帮助!

import org.apache.commons.lang3.StringEscapeUtils;

public class ChamorroEntry {

  private String chamorro, english, notes;

  public ChamorroEntry(String chamorro, String english, String notes) {
    this.chamorro = StringEscapeUtils.unescapeHtml4(chamorro.trim());
    this.english = StringEscapeUtils.unescapeHtml4(english.trim());
    this.notes = notes.trim();
  }

  @Override
  public boolean equals(Object object) {
    if (!(object instanceof ChamorroEntry)) {
      return false;
    }
    if (this == object) {
      return true;
    }
    ChamorroEntry entry = (ChamorroEntry) object;
    return chamorro.equals(entry.chamorro) && english.equals(entry.english)
        && notes.equals(entry.notes);
  }

  @Override
  public int hashCode() {
    return java.util.Objects.hash(chamorro, english, notes);
  }

  public static void main(String... args) {
    ChamorroEntry entry1 = new ChamorroEntry("Åguigan", "Second island south of Saipan. Åguihan.", "");
    ChamorroEntry entry2 = new ChamorroEntry("Åguihan", "Second island south of Saipan. Åguigan.", "");
    System.err.println(entry1.equals(entry2)); // returns false
    System.err.println(entry1.hashCode() + "\n" + entry2.hashCode()); // returns same hash code!
  }
}

最佳答案

其实,你的触发纯属巧合。 :)

Objects.hash 恰好是通过连续添加每个给定对象的哈希码,然后将结果乘以 31 来实现的,而 String.hashCode 与它的每一个字符。巧合的是,您使用的“English”字符串中的差异与“Chamorro”字符串中的相同差异正好发生在距字符串末尾多一个偏移处,因此一切都完美抵消了。恭喜!

尝试使用其他字符串,您可能会发现它按预期工作。正如其他人已经指出的那样,严格来说,这种效果实际上并没有错,因为哈希码可能会正确碰撞,即使它们代表的对象不相等。如果有的话,尝试找到更高效的哈希可能是值得的,但我认为在现实情况下几乎没有必要。

关于java - equals 和 hashCode : Is Objects. 哈希方法坏了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13785353/

相关文章:

c# - 等于、GetHashCode、EqualityComparers 和模糊相等

mysql - vb.net 中登录表单的散列密码

java - 字符串 GUID 的哈希码为奇数或偶数的概率是多少?

java - 更改遗留代码中的不可变类

具有最大 N 个相等元素位置的 C++ vector

java - 如何在Android上模拟位置?

java - 单例意味着哈希码总是返回相同的吗?

Java HashSet 包含不起作用的函数

java - 如何删除数组中的单词?

java - 在 Windows 上使用 "storm jar"命令远程部署 Storm 拓扑