JCF之equals()与hashCode()关系详解 (二)

2014-11-24 07:51:04 · 作者: · 浏览: 3
面重现一下Hashtable的添加元素方法:

[java] public synchronized V put(K key, V value) {
//确定value非空,若为空,则抛出NullPointerException
if (value == null) {
throw new NullPointerException();
}
// 接下来判断传入的key是否已经存在hashtable中,而这需要判断hashCode是否相等以及equal()是否为true
Entry tab[] = table;
//得到当前key的hash值,如果Key为Null,也将抛出NullPointerException
int hash = key.hashCode();
//根据hash值算出索引
int index = (hash & 0x7FFFFFFF) % tab.length;
//判断table[index]处是否已经非空
for (Entry e = tab[index] ; e != null ; e = e.next) {
//如果table[index]非空
//判断table[index]处key的hash值与传入的key的hash值是否相等
// 如果二者hash值相等,则判断equals()是否为真
if ((e.hash == hash) && e.key.equals(key)) {
//如果通过了判断,则说明table[index]处的key和传入的key是相同的,用传入的value替换table[index]的value
V old = e.value;
e.value = value;
return old;
}
}
modCount++;
}
public synchronized V put(K key, V value) {
//确定value非空,若为空,则抛出NullPointerException
if (value == null) {
throw new NullPointerException();
}
// 接下来判断传入的key是否已经存在hashtable中,而这需要判断hashCode是否相等以及equal()是否为true
Entry tab[] = table;
//得到当前key的hash值,如果Key为Null,也将抛出NullPointerException
int hash = key.hashCode();
//根据hash值算出索引
int index = (hash & 0x7FFFFFFF) % tab.length;
//判断table[index]处是否已经非空
for (Entry e = tab[index] ; e != null ; e = e.next) {
//如果table[index]非空
//判断table[index]处key的hash值与传入的key的hash值是否相等
// 如果二者hash值相等,则判断equals()是否为真
if ((e.hash == hash) && e.key.equals(key)) {
//如果通过了判断,则说明table[index]处的key和传入的key是相同的,用传入的value替换table[index]的value
V old = e.value;
e.value = value;
return old;
}
}
modCount++;
}
相同的对象(x.equals(y)==true)需要hash到hash表的同一个位置,如果相同的对象(x.equals(y)==true)hashCode不同,那么便无法保证这一点。

比如:

String s1 = new String("love");

String s2 = new String("love");

s1.equals(s2)==true,所以这两个对象是相等的,如果此时s1.hashCode()!=s2.hashCode(),那么在添加元素时便可能获得不同的索引,
即相同的对象添加到了hash容器的不同位置。这显然又违反了hash容器的初衷。


摘自 JieTouLangRen的专栏