jdk源码——hashmap的1.8与1.7比较

1.8链表的定义基本上与1.7相同,但是类名改为Node,但是node实现了Map.Entry接口,实质是一样的

 static class Node<K,V> implements Map.Entry<K,V> {

1.8的hash值的算法更加直观一点,就是key的hashcode与无符号右移16位的hashcode异或,然后返回。这是为了当length比较小的时候,也能保证考虑到高低Bit位都参与到Hash的计算中,同时不会有太大的开销。

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    } 

 tableSizeFor主要功能是返回一个比给定整数大且最接近的2的幂次方整数,返回的是n+1,实例如下,右移一位,把最高位的1后面一位也变成了1,通过右移,把最高位后面全部置换成1,最后n+1,即为最接近传入数的2的幂次方整数

 static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

 hashmap1.8的数据结构如下,当链表的长度不小超过8的话就按链表存储,若是超过了8,那么通过treeifyBin 转化为红黑树

  final void treeifyBin(Node<K,V>[] tab, int hash) {
        int n, index; Node<K,V> e;
        if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
            resize();
        else if ((e = tab[index = (n - 1) & hash]) != null) {
            TreeNode<K,V> hd = null, tl = null;
            do {
                TreeNode<K,V> p = replacementTreeNode(e, null);//把每个及节点转化为TreeNode
                if (tl == null)
                    hd = p;
                else {
                    p.prev = tl;
                    tl.next = p;
                }
                tl = p;
            } while ((e = e.next) != null);
            if ((tab[index] = hd) != null)
                hd.treeify(tab);
        }
    }

 

  TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) {
        return new TreeNode<>(p.hash, p.key, p.value, next);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
回答: 在HashMap的实现中,1.8版本相对于1.7版本进行了一些优化和改进。首先,在1.8版本中,对高位运算的算法进行了优化,通过将hashCode()的高16位与低16位进行异或运算来实现:(h = k.hashCode()) ^ (h >>> 16)。这样做可以在数组table的长度较小的情况下,保证高位和低位都参与到Hash的计算中,同时不会带来太大的开销。这个改进主要考虑了速度、功效和质量的因素。\[1\] 其次,在定位到哈希桶数组的位置方面,1.8版本也进行了改进。为了使HashMap中的元素位置尽量分布均匀,每个位置上只有一个元素,从而优化查询效率,1.8版本引入了新的定位数组索引位置的方法。这个方法是通过对hash值进行与运算来实现的,即h & (length-1)。这样可以直接确定对应位置的元素,而不需要遍历链表,大大提高了查询效率。\[2\] 另外,1.8版本还对相同key和不同key的处理方式进行了改进。对于相同的key,新值会覆盖旧值,并返回旧值。而对于不同的key,但是计算出来的hash值相同的情况下,1.8版本会在数组中生成链表,而不是像1.7版本那样直接放入数组中。这样可以更好地处理冲突,提高了性能。\[3\] 综上所述,1.8版本相对于1.7版本在高位运算、定位数组索引位置和处理冲突等方面进行了优化和改进,从而提高了HashMap的性能和效率。 #### 引用[.reference_title] - *1* *2* [hashmap源码解析,JDK1.81.7区别](https://blog.csdn.net/weixin_30709929/article/details/98702913)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [hashmap1.71.8区别](https://blog.csdn.net/zhangleiyes123/article/details/126490140)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值