我们都知道,如果equals
方法返回true
,则两个对象相等。
任何人都可以举一个示例,其中两个对象具有相同的 hash
值,但实际上是不同的?
我假设您熟悉与覆盖equals()
和hashCode()
关联的合同,以及易于碰撞的哈希码实现的含义。鉴于此,以下琐碎的示例使用一个容纳两个整数并实现非常简单的主题的对象,并证明拥有两个不相等但具有相同哈希码的对象是多么容易。提供更复杂的标签算法可以减轻这种情况。
运行主要的输出是:
hashCodes: ih1: 6, ih2: 6
equals: false
示例代码:
package example.stackoverflow;
public class IntHolder
{
private Integer primaryData;
private Integer secondaryData;
public IntHolder(Integer primaryData, Integer secondaryData)
{
this.primaryData = primaryData;
this.secondaryData = secondaryData;
}
@Override
public int hashCode()
{
return ((primaryData == null) ? 0 : primaryData.hashCode()) +
((secondaryData == null) ? 0 : secondaryData.hashCode());
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IntHolder other = (IntHolder) obj;
if (primaryData == null)
{
if (other.primaryData != null)
return false;
}
else if (!primaryData.equals(other.primaryData))
return false;
if (secondaryData == null)
{
if (other.secondaryData != null)
return false;
}
else if (!secondaryData.equals(other.secondaryData))
return false;
return true;
}
public static void main(String[] args)
{
IntHolder ih1 = new IntHolder(1, 5);
IntHolder ih2 = new IntHolder(3, 3);
System.out.println("hashCodes: ih1: " + ih1.hashCode() + ", ih2: " + ih2.hashCode());
System.out.println("equals: " + ih1.equals(ih2));
}
}
供参考,Eclipse的自动生成的hashcode()用于InTholder类是:
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((primaryData == null) ? 0 : primaryData.hashCode());
result = prime * result
+ ((secondaryData == null) ? 0 : secondaryData.hashCode());
return result;
}
String str1="abcdef";
String str2="abcdfG";
他们都有相同的哈希码,等于方法返回false。
public class Employee {
protected long employeeId;
public boolean equals(Object o){
if(o == null) return false;
if(!(o instanceof) Employee) return false;
Employee other = (Employee) o;
return this.employeeId == other.employeeId;
}
public int hashCode(){
return (int) this.employeeId;
}
}
在此示例中,我们已经覆盖了等价方法 - 两个员工在拥有同一员工ID时相同。
如果两个员工对象相等,则它们也将具有相同的哈希代码。
您的ANS -
在此示例中,我们还实现了哈希码 - 哈希码是舍入到int的员工。这意味着许多员工ID可能会导致相同的哈希代码,但是这些员工对象仍然不平等,因为他们没有相同的员工ID。