0

我试图了解如果我们hashCode()错误地实施方法会面临哪些问题。

例如,我尝试创建一个示例类HashEx,该类为该类的所有实例静态返回相同的哈希值 (100),然后尝试使用HashExin 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;
    }
}
4

1 回答 1

0

一切都会正常工作(只要你equals(Object)在你的HashEx类中正确实现),你不会看到任何不正确的行为。

HashSet但是,当您在您的(或作为 a 中的键)中获得大量这些对象时HashMap,您将开始看到非常糟糕的性能。对象根据它们被放入桶中hashCode,并且每当完成其中一项收集操作时,都必须线性搜索同一桶中的所有对象。

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

如果对象相反,hashCode那么操作根本不会减慢(很多),并且会更快地耗尽内存。

于 2012-07-08T15:36:25.753 回答