在hashmap冲突中检索实际值
问题描述:
两个不同的对象可以具有相同的hashCode并且相等。如何通过引用获取实际对象?在hashmap冲突中检索实际值
例如: -
class Dog {
public String name;
public Dog(String n){
this.name = n;
}
public boolean equals(Object o){
if((o instanceof Dog) && ((Dog)o).name.length() == this.name.length()){
return true;
}else{
return false;
}
}
public int hashCode(){
return name.length();
}
@Override
public String toString(){
return name;
}
}
public class MapTest {
public static void main(String ar[]){
Map<Object, Object> m = new HashMap<Object, Object>();
Dog d1 = new Dog("clover");
Dog d2 = new Dog("abcdef");
m.put(d1, new Dog("aiko1"))
m.put(d2, new Dog("aiko"));
System.out.println(m.get(d1));
System.out.println(m.get(d2));
}
}
输出: -
爱子
爱子
然而D1的值是aiko1但是当我们取,打印的值是蓝子。我们如何获取实际的d1值?
答
让我来解释一下HashMap
在这种情况下是如何工作的。
- 首先,你必须重写
hashCode()
方法 -
HashMap
会先看看它。 - 您正在使用
length
的name
字段作为哈希码。 - “三叶草”和“ABCDEF”都将返回相同的散列码,这是6
- 现在,它的碰撞状态,因此
HashMap
会掉下来equals
方法来检查它进一步指出,再被你覆盖。 - 但是在
equals
这里再次做同样的事情。在这里你也比较长度为name
的字段。 - 在这种情况下,两个键都是相同的,因此它会覆盖上一个值。
您可以验证它,但在main
方法末尾调用m.size()
。
但我建议使用String
作为名称字段的关键字。
Map<String, Object> m = new HashMap<String, Object>();
在这种情况下,你不需要重写hashCode
以及equals
。
import java.util.HashMap;
import java.util.Map;
class Dog {
public String name;
public Dog(String n) {
this.name = n;
}
@Override
public String toString() {
return name;
}
}
public class MapTest {
public static void main(String ar[]) {
Map<String, Object> m = new HashMap<String, Object>();
Dog d1 = new Dog("clover");
Dog d2 = new Dog("abcdef");
m.put(d1.name, new Dog("aiko1"));
m.put(d2.name, new Dog("aiko"));
System.out.println(m.get(d1.name));
System.out.println(m.get(d2.name));
}
}
答
因为两个钥匙(d1
和d2
)是相等的(根据您的实现的eqauls(Object)
),没有在地图上两个元素 - 唯一的一个。第二次致电put
覆盖以前的值。
我不明白你的问题。你已经有'd1'。你正在使用它作为关键。 –
缺点是你的'equals()'方法。你说狗(“三叶草”)和Dog(“abcdef”)一样。那么你期望什么?键d2和d1是同一个!因此m.put(d2,...)替换条目(d1,Dog(“aiko1”))。 –
我想了解hashmap如何工作,如果两个对象具有相同的哈希码?如果hashcode是相同的,那么通过Hashcode合约,那么通过equals方法对象应该是相同的。有什么办法可以检索Java中的d1值,当hashcodes是相同的? – Sanket