如果我们错误地实施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;
}
}
答案 0 :(得分:0)
所有内容都正常工作(只要您在equals(Object)
课程中正确实施HashEx
),您将看不到任何不正确的行为。
但是当你在HashSet
(或HashMap
中的键)中获得大量这些对象时,你会发现性能非常差。根据对象hashCode
将对象放入存储桶中,并且只要完成其中一个收集操作,就必须线性搜索同一存储桶中的所有对象。
因此,一个更好的测试来证明问题就是编写一个循环,它只是开始添加越来越多的对象(直到程序耗尽内存或者你杀掉它)并且每10,000个对象打印一个状态消息。您将看到添加操作变得越来越慢(以二次方式)。
如果对象改为使用不同的hashCode
,那么操作根本不会减慢(很多),并且内存会快得多。