JDK8中对hash算法和寻址算法的优化

JDK8中对hash算法和寻址算法的优化

1. 寻址算法

在插入和查找数据的时候,会根据一个 key 得到对应的 hash 值(传入的参数,已知),根据这个 hash 值进行得到元素在数组的下标位置,这个计算过程就是寻址算法。

	/**
     * Implements Map.get and related methods.
     *
     * @param hash hash for key
     * @param key the key
     * @return the node, or null if none
     */
    final Node<K,V> getNode(int hash, Object key) {
        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (first = tab[(n - 1) & hash]) != null) {
            if (first.hash == hash && // always check first node
                ((k = first.key) == key || (key != null && key.equals(k))))
                return first;
            if ((e = first.next) != null) {
                if (first instanceof TreeNode)
                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                do {
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        return e;
                } while ((e = e.next) != null);
            }
        }
        return null;
    }
  1. 我们知道了一个 key 的 hash 值,用这个 hash 值根数组长度取模,就可以得到下标位置,实际在代码中,采用了与运算 ( 两个都是 1 ,结果为 1 ,否则为 0 )代替了取模运算
  2. 公式: ( n -1 ) & hash 其中 n 为数组长度

为什么用与运算?

  1. 对于现代的处理器来说,除法和求余数(模运算)是最慢的动作
  2. 数学公式:
    a % b = ( b -1 ) & a, 当b是2的指数时,等式成立

2. hash哈希算法

  1. 寻址算法:hash -> index 需要根据 hash 值计算数组下标
  2. 哈希算法:key.hashCode() -> hash 就是根据一个 key ,通过计算得到它对应的 hash 值
static final int hash(Object key){
	int h;
	return (key == null)? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
  1. 为什么不直接使用它的hashCode?
    如果直接使用 hashcode 作为 hash 值
    寻址算法: ( n - 1 ) & hash
条件地址
A 的 hashCode :1000 0100 0111 0001 0000 0111 1000 0000
n - 1 = 150000 0000 0000 0000 0000 0000 0000 1111
与运算结果0000 0000 0000 0000 0000 0000 0000 1111
B 的 hashCode0111 0111 0011 1000 1010 0001 0100 0000
n - 1 = 150000 0000 0000 0000 0000 0000 0000 1111
与运算结果0000 0000 0000 0000 0000 0000 0000 1111

运算得出来的结果相同,这样的散列结果太让人失望了,这很明显不是一个好的散列算法

把 hashcode 向右移 16 位,然后再和原来的 hashcode 做异或运算 (相同为 0 , 不同为 1)

条件地址
A 的 hashCode :1000 0100 0111 0001 0000 0111 1000 0000
右移 16 位0000 0000 0000 0000 1000 0100 0111 0001
异或运算1000 0100 0111 0001 1000 0011 1111 0001
n - 1 = 150000 0000 0000 0000 0000 0000 0000 1111
与运算结果0000 0000 0000 0000 0000 0000 0000 0001
B 的 hashCode0111 0111 0011 1000 1010 0001 0100 0000
右移 16 位0000 0000 0000 0000 0111 0111 0011 1000
异或运算0111 0111 0011 1000 1101 0110 0100 1000
n - 1 = 150000 0000 0000 0000 0000 0000 0000 1111
与运算结果0000 0000 0000 0000 0000 0000 0000 1000

通过哈希算法的优化,一定程度避免了 hash 冲突,让数据更加散列。

hashCode相关:
https://zhuanlan.zhihu.com/p/33915892
https://www.cnblogs.com/dolphin0520/p/3681042.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值