JDK1.8 HashMap运行原理

JDK1.8 HashMap运行原理

一,什么是HashMap

  1. HashMap是桶加链表结构。
  2. 非synchronized,效率高。
  3. 允许空key,但又因为key不能重复,故同一个HashMap中只会有一个空key
    二,put方法
  4. 当我们选择put一个key与value时,程序会首先对key进行hashCode,然后再对hashCode进行异或(^)变成hash,也就是经常说得扰乱,作用是减少hashCode相同产生的碰撞
    如图:
    在这里插入图片描述
  5. 当hash与桶的hash相同时进行qut,如有此桶里面有值,则将新值放到前一个值的next中,依次类推。但是桶下面的链表只能拥有最多8个元素,如超过8个元素将采用红黑树的方式进行表达元素顺序,采用红黑树的目的是为了防止链表太长,会影响获取key时间,当红黑树的长度小于8时,便将红黑树转换为链表,在元素8以下的时候,链表的效率高于红黑树。

3.见博客上说hashMap的加载因子默认为0.75,初始长度为16,当map长度大于长度乘以加载因子时扩容为原长度的一倍。这是对的,但看源码发现有一种特殊的情况.
例如:当只有8或9个的元素,但是这几个元素的hash相同,全部在一条链表上,当列表长度大于等于8时,会调用如下方法:

     //此方法作用是将链表转换为红黑树

    final void treeifyBin(Node<K,V>[] tab, int hash) {
            int n, index; Node<K,V> e;
           //MIN_TREEIFY_CAPACITY==64,tab.length为当前map长度
            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);
                    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);
            }
        }

由此方法可以看出,当map的长度小于64时,会调用resize()方法,此方法为扩容(扩容时会重新计算hash值,进行重新放数据,这也挺消耗性能),从上面可以看出即使map的长度没有大于长度*加载因子的长度时也是会扩容的,也可以看出来链表转红黑树在map的长度大于64时才会进行。

get方法
在这里插入图片描述

首先是获取key的hash与map中的hash对比,如没有,返回null,如命中,则获取第一个元素,进行equlas,如不相同,判断元素中的next是否为空,如不为空继续判断,如不相同,继续判断,当有相同时进行返回,如无返回null。

也许大家会有一个疑问,便是为什么采用红黑树而不采用二叉树呢?
让我来巴拉一波,那是因为二叉树在某一种极端情况下,与链表是一样的,极端情况下指得是,当只有左子树或只有右子树时,此时二叉树的作用是与链表一样的,不方便访问,而红黑树被称为平衡二叉树,所以不会出现这种情况,对红黑树感兴趣的同学可以自行百度以下哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值