hashCode()方法的作用
在Java中,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。
用HashMap举例说明下,为了判断HashMap中存在不存在key,HashMap不用遍历里面的所有元素进行判断再取值,为什么呢?HashMap类中维护了一个数组(俗称桶或箱子),桶的类型是链表或者红黑树,每次进行put运算时,都会对key的hashCode值进行hash运算,得到的hash值与数组元素的个数进行与运算,目的是拿到该key对应的桶的位置,即数组索引下标,再遍历桶(链表或红黑树)判断key是够存在,这样只需遍历对应桶的元素即可。同时,为了让HashMap中的元素尽量发散,即尽可能每个桶的元素都平均,不会出现其中一个桶元素很多,其他桶元素很少的情况,于是使用hashCode方法进行hash运算,让各个元素都发散到各个桶中,减少遍历桶元素的时间,大大提高了HashMap的性能。
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
// 计算hash值,并找到key对应的table桶位置
if ((p = tab[i = (n - 1) & hash]) == null)
// 该桶元素为空,直接放元素进去该桶
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
// 总是比较第一个元素
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
// 桶是红黑树
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
// 遍历桶里面的元素并比较是否eqlues等于key
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
......
}
......
}
2. equals()和hashCode()方法
重写equals方法的同时,必须重写hashCode方法,因为重写了equals方法后,如果有散列集合操作的话,如HashMap的put操作,需要使用hashCode方法进行hash运算,如果equals相等的两个类,但是无法保证hashCode方法返回的值一样,如果这两个类分别进行put操作的话,可能会保存到不同的数组下标中而不是同一个。
本文深入探讨了Java中hashCode方法的作用及其实现原理,通过HashMap的工作机制来解释hashCode如何提高散列集合性能,同时强调了equals与hashCode方法一致性的重要性。
2304

被折叠的 条评论
为什么被折叠?



