日期:2014-05-20  浏览次数:20745 次

HashMap的key的问题
Java code

import java.util.HashMap;
import java.util.Map;

class Dog{
    public String name;
    public Dog(String name){
        this.name = name;
    }
    public boolean equals(Object o){
        if((o instanceof Dog) && (((Dog)o).name == name)){
            return true;
        }else{
            return false;
        }
    }
    public int hashCode(){
        return name.length();
    }
    public String toString(){
        return name;
    }
}

public class Test111226{
    public static void main(String[] args) {
        Map<Object, Object> m = new HashMap<Object, Object>();
        Dog d1 = new Dog("clover");
        m.put(d1, "DDDDOG");
        System.out.println(m.get(d1));
        d1.name = "magnolia";
        for(Object o: m.keySet()){
            System.out.println(o.hashCode());
            System.out.println(o.toString());
        }
        System.out.println("================");
        System.out.println(d1.hashCode());
        System.out.println(d1.toString());
        System.out.println("----------------");
        System.out.println(m.get(d1));
        
    }
}



输出:
DDDDOG
8
magnolia
================
8
magnolia
----------------
null

请问:为什么第一次m.get(d1)的时候能返回"DDDDOG",而将d1.name修改后就返回了null(修改d1的name后,可以看到map中的key的hashCode和name也跟着变了,hashCode和equals仍然相同,为什么get不到呢?)

------解决方案--------------------
hash之所以称为hash就是因为存储的时候是根据hashCode确定存储的位置的。开始的时候hashCode是6,根据这个映射到一个存储位置;之后你更改了对象的属性,影响到了hashCode的计算,变成了8,现在系统根据8来映射到了另一个存储位置,然后使用equals函数判断这个位置的对象和要get的对象是否相等,相等的话就返回,否则返回null。
keySet返回key的集合,遍历输出的话是肯定没问题的了。
------解决方案--------------------
hashcode相同的两个对象,不一定equals
但是两个equals的对象, hashcode一定相同。 楼主现在明白了吗??


------解决方案--------------------
Map中请使用 不变的值作为key,不要使用可变的