我有一个类以下equals()和hashCode()方法
@Override
public boolean equals(Object o)
{
if (this == o) { return true; }
if (o == null || getClass() != o.getClass()) { return false; }
Phrases that = (Phrases) o;
if (this.hashCode() == o.hashCode()) { return true; } //retry clover coverage test
if (exitMsg != null ? !exitMsg.equals(that.exitMsg) : that.exitMsg != null)
{ return false; }
if (introMsg != null ? !introMsg.equals(that.introMsg) : that.introMsg != null)
{ return false; }
if (msg != null ? !msg.equals(that.msg) : that.msg != null)
{ return false; }
if (phrase != null ? !phrase.equals(that.phrase) : that.phrase != null)
{ return false; }
if (title != null ? !title.equals(that.title) : that.title != null)
{ return false; }
return true;
}
@Override
public int hashCode()
{
int result = phrase != null ? phrase.hashCode() : 0;
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + (introMsg != null ? introMsg.hashCode() : 0);
result = 31 * result + (msg != null ? msg.hashCode() : 0);
result = 31 * result + (exitMsg != null ? exitMsg.hashCode() : 0);
return result;
}
Run Code Online (Sandbox Code Playgroud)
我试图弄清楚为什么三叶草无法告诉我的哈希码方法已经运行.我添加了这一行:
if (this.hashCode() == o.hashCode()) { return true; } //retry clover coverage test
Run Code Online (Sandbox Code Playgroud)
根据三叶草每次这个等于方法运行if (this == o) { return true; }是假的但是if (this.hashCode() == o.hashCode()) { return true; }是真的.
题:
为什么评估this == o和this.hashCode() == o.hashCode()不评估相同的结果?
根据定义,哈希码包含的信息少于源数据.这意味着碰撞是可能的,在这种情况下,您将拥有两个具有相同哈希码但不相等的对象.
Java的一般要求hashCode()是相反的方向:
equals关系所持有的两个对象必须产生相同的哈希码(相反的情况并非如此)基本上,关键是你不能将哈希码用作唯一标识符(事实上JDK数据结构在内部管理冲突).
这没有任何关系,==因为它只比较了对象的引用(内存地址),对于这些对象hashCode()和equals将是非常相同的.
如果你看一下hashCode()你可以看到,如果除了一个字段之外的所有字段都为空,但是哪个字段不同,则计算的哈希码是相同的,这清楚地证明了您可以轻松生成冲突的事实.
如果你想要更强的东西,你应该考虑使用MessageDigest哪个产生的摘要比a更长int(因此能够容纳更多的信息=不太可能发生碰撞).但即使有他们也不会有任何保证.