[英]Working of hashcode() and equals() in java?
这是我们将用于放入hasmap的类。 它已经覆盖了equals()
和hashcode()
方法。
class Dog
{
public String name;
public Dog(String n)
{
name=n;
}
@Override
public int hashCode() {
System.out.println("in hashcode");
return name.length();
}
@Override
public boolean equals(Object obj) {
System.out.println("in equals");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Dog other = (Dog) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
此代码主要
Map<Object,Object> m=new HashMap<Object,Object>();
Dog d1=new Dog("clover");
m.put(d1,"Dog Key");
System.out.println(m.get(d1));
产生
in hashcode
in hashcode
Dog Key
但是下面的代码
Map<Object,Object> m=new HashMap<Object,Object>();
Dog d1=new Dog("clover");
m.put(d1,"Dog Key");
System.out.println(m.get(new Dog("clover")));
产生
in hashcode
in hashcode
in equals
Dog Key
如您所见,第二个输出中有一个对equals()
方法的调用。 为什么会这样?
我的第二个问题
如果更改键Map的名称属性,则m = new HashMap();
Dog d1=new Dog("clover");
m.put(d1,"Dog Key");
d1.name="arthur";
System.out.println(m.get(new Dog("clover")));
o / p是
in hashcode
in hashcode
in equals
null
即使我更改了键值,但我仍在尝试通过提供相同的键来检索该值。 那为什么要检索null呢?
对于第一个问题: HashMap
需要调用equals()
来确认两个具有相同哈希码的Dog
对象实际上是相等的。 它不需要第一次调用equals()
,因为它使用==
来检查使用与先前指定的对象完全相同的特殊情况。
对于第二个问题:您更改了一个数据成员,该成员更改了哈希码的计算以及equals()
的结果。 这特别违反了规则,因此地图已损坏; 在那时,任何事情都可能发生。 切勿将具有可变数据的对象用作HashMap
键!
这是因为在将d1=new Dog("clover")
d1.name="arthur";
,您将其名称更改为d1.name="arthur";
因此,名称为arthur
Dog不再等于new Dog("clover")
。
因此,首先首先检查密钥哈希码,然后将其匹配为"clover".length
等于"arthur".length
,这可以标识保存对象的存储桶。 之后,执行equals()
检查以从存储桶中获取正确的对象,但此操作失败,因为您的密钥不等于所提供的密钥。
实际上,使用可变字段进行哈希码计算不是一个好习惯。
让我们考虑一下HashMap的工作原理。
对HashMap使用适当的哈希码算法和容量设置,通常可以达到O(1)性能。
现在让我们考虑您的问题:
但是,如果您在其中更改代码:
Dog d1=new Dog("clover");
m.put(d1,"Dog Key");
d1.name="arthur";
System.out.println(m.get(d1));
最后应该给你带来麻烦。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.