马州州 发表于 2012-8-7 17:01
程序是我们写的没错
我想问的是,我们在设计程序的时候就已经尽可能使每个对象的哈希值不同
这句话有问题, ...
HashSet的实现是通过HashMap的KeySet做为存储结构的,大家都知道哈希算法为了避免键值冲突,一般有两个方法:二次哈希和链地址法。则HashMap就是用的链地址法。
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
看上面代码中下划线的黑体字,就是用hashCode()方法得到键值的桶(桶的概念是一个具有相同哈希值的容器)地址,然后才在一个桶中调用equals方法比较对象是否相等。
其实到这里我们已经知道了hashCode为什么一定要重写了。如果为两个实例即使equals方法成立,可是如果不在一个桶中,则都本不会调用equals方法比较了。
|