equals和hashCode:Objects.hash方法被破坏了吗? [英] equals and hashCode: Is Objects.hash method broken?

查看:176
本文介绍了equals和hashCode:Objects.hash方法被破坏了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java 7,我在下面有以下课程。我正确地实现了等于 hashCode ,但问题是等于在下面的main方法中返回 false hashCode 返回两个对象的相同哈希码。我可以让更多的眼睛看这堂课,看看我在这里做错了吗?

I am using Java 7, and I have the following class below. I implemented equals and hashCode correctly, but the problem is that equals returns false in the main method below yet hashCode returns the same hash code for both objects. Can I get more sets of eyes to look at this class to see if I'm doing anything wrong here?

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

UPDATE: I replaced the line on which I call the Objects.hash method with my own hash function: chamorro.hashCode() + english.hashCode() + notes.hashCode(). It returns a different hash code, which is what hashCode is supposed to do when two objects are different. Is the Objects.hash method broken?

我们非常感谢您的帮助!

Your help will be greatly appreciated!

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!
  }
}


推荐答案

实际上,你碰巧触发了纯粹的巧合。 :)

Actually, you happened to trigger pure coincidence. :)

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

Objects.hash happens to be implemented by successively adding the hash code of each given object and then multiplying the result by 31, while String.hashCode does the same with each of its characters. By coincidence, the differences in the "English" strings you used occur at exactly one offset more from the end of the string as the same difference in the "Chamorro" string, so everything cancels out perfectly. Congratulations!

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

Try with other strings, and you'll probably find that it works as expected. As others have already pointed out, this effect is not actually wrong, strictly speaking, since hash codes may correctly collide even if the objects they represent are unequal. If anything, it might be worthwhile trying to find a more efficient hash, but I hardly think it should be necessary in realistic situations.

这篇关于equals和hashCode:Objects.hash方法被破坏了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆