检索哈希映射冲突中的实际值



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

例如:-

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,但是当我们获取时,打印的值是 aiko。我们如何获取实际的 d1 值?

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

  • 首先,您已经覆盖了hashCode()方法
  • HashMap先看看。
  • 您正在使用name字段length作为哈希代码。
  • "
  • Clover"和"abcdef"都将返回相同的哈希代码,即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));
    }
}

由于您的两个键(d1d2 )是相等的(根据您对 eqauls(Object) 的实现),映射中没有两个元素 - 只有一个。对 put 的第二次调用将覆盖以前的值。

最新更新