检索hashmap碰撞中的实际值

时间:2014-03-31 05:38:15

标签: java data-structures map hashmap

两个不同的对象可以具有相同的hashCode并且相等。如何通过引用获取实际对象?

例如: -

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));
   }
}

OutPut: -
爱子
爱子

然而,d1的值是aiko1,但是当我们取出时,打印的值是aiko。我们如何获取实际的d1值?

2 个答案:

答案 0 :(得分:0)

由于您的密钥(d1d2)相等(根据您对eqauls(Object)的实现),因此地图中没有两个元素 - 只有一个。第二次调用put 会覆盖之前的值。

答案 1 :(得分:0)

让我向您解释HashMap在这种情况下的工作原理。

  • 首先,您已覆盖hashCode()方法
  • HashMap会先查看。
  • 您使用length name字段作为哈希码。
  • &#34;三叶草&#34;和&#34; abcdef&#34;两者都将返回相同的哈希码,即6。
  • 现在它是一个碰撞状态,因此HashMap将落到equals方法,以进一步检查它,再次被你覆盖。
  • 但是在equals再次,你在做同样的事情。您还可以在此处比较name字段的长度。
  • 在这种情况下,两个键都相同,因此它将覆盖最后一个值。

您可以对其进行验证,但在m.size()方法的末尾调用main


但我建议使用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));
    }
}