理解不正确实现的哈希码方法的负面影响

时间:2012-07-08 15:29:21

标签: java hashcode

如果我们错误地实施hashCode()方法,我想了解我们可能遇到的问题。

例如,我尝试创建一个示例类HashEx,它静态地为该类的所有实例返回相同的哈希值(100),然后尝试在HashEx中使用HashSet / HashMap具有不同的操作:

HashSet -> add,read,contains
HashMap -> put,get

到目前为止,所有操作似乎都运作良好。对这个狂野想法的任何想法?我试图了解hashCode()的错误实现会在哪里产生问题?

public class HashEx {

    public int id;
    public String name;

    public static void main(String[] args){

        HashEx e1 = new HashEx();
        e1.id=1;
        e1.name="Tom";

        HashEx e2 = new HashEx();
        e2.id=2;
        e2.name="Jerry";

        // set
        HashSet<HashEx> myset = new HashSet<HashEx>();
        myset.add(e1);
        myset.add(e2);

        System.out.println("Set size : "+ myset.size());
        for(HashEx e : myset){
            System.out.println("id: " + e.id + ", name: " + e.name);
        }

        HashEx e4 = new HashEx();
        e4.id = 2;
        e4.name = "Jerry";

        System.out.println("myset.contains(e4) : " + myset.contains(e4));

        // map
        HashMap<HashEx, String> map = new HashMap<HashEx, String>();

        map.put(e1, "Tom");
        map.put(e2, "Jerry");

        System.out.println("Map size : "+ map.size());
        System.out.println(map.get(e1));
        System.out.println(map.get(e2));
    }

    @Override
    public boolean equals(Object obj) {
        if(((HashEx)obj).id != id)
            return false;
        if(!((HashEx)obj).name.equals(name))
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        return 100;
    }
}

1 个答案:

答案 0 :(得分:0)

所有内容都正常工作(只要您在equals(Object)课程中正确实施HashEx),您将看不到任何不正确的行为。

但是当你在HashSet(或HashMap中的键)中获得大量这些对象时,你会发现性能非常差。根据对象hashCode将对象放入存储桶中,并且只要完成其中一个收集操作,就必须线性搜索同一存储桶中的所有对象。

因此,一个更好的测试来证明问题就是编写一个循环,它只是开始添加越来越多的对象(直到程序耗尽内存或者你杀掉它)并且每10,000个对象打印一个状态消息。您将看到添加操作变得越来越慢(以二次方式)。

如果对象改为使用不同的hashCode,那么操作根本不会减慢(很多),并且内存会快得多。

相关问题