在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值?

+0

我不明白你的问题。你已经有'd1'。你正在使用它作为关键。 –

+0

缺点是你的'equals()'方法。你说狗(“三叶草”)和Dog(“abcdef”)一样。那么你期望什么?键d2和d1是同一个!因此m.put(d2,...)替换条目(d1,Dog(“aiko1”))。 –

+0

我想了解hashmap如何工作,如果两个对象具有相同的哈希码?如果hashcode是相同的,那么通过Hashcode合约,那么通过equals方法对象应该是相同的。有什么办法可以检索Java中的d1值,当hashcodes是相同的? – Sanket

让我来解释一下HashMap在这种情况下是如何工作的。

  • 首先,你必须重写hashCode()方法
  • HashMap会先看看它。
  • 您正在使用lengthname字段作为哈希码。
  • “三叶草”和“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)); 
    } 
} 

因为两个钥匙(d1d2)是相等的(根据您的实现的eqauls(Object)),没有在地图上两个元素 - 唯一的一个。第二次致电put覆盖以前的值。