equals和hashCode:Objects.hash方法被破坏了吗?

BJ *_*ruz 5 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!
  }
}
Run Code Online (Sandbox Code Playgroud)

Dol*_*000 12

实际上,你恰好触发了纯粹的巧合.:)

Objects.hash碰巧是通过连续添加每个给定对象的哈希码然后将结果乘以31来实现,而String.hashCode对每个字符执行相同的操作.巧合的是,你使用的"英语"字符串的差异恰好出现在字符串末尾的一个偏移处,与"Chamorro"字符串中的差异相同,所以一切都完全取消了.恭喜!

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


Aff*_*ffe 6

不要求不等对象必须具有不同的hashCodes.期望等对象具有相等的hashCodes,但不禁止散列冲突. return 1; 如果不是非常有用的话,它将是hashCode的完美合法实现.

毕竟,只有32位可能的哈希码和无限数量的可能对象:)有时会发生冲突.