HashMap源码

对hash的理解

将任意长度的输入,转化为固定长度的输出,会产生hash冲突,举例(有10个苹果,9个盒子,则肯定有一个盒子里面装两个)

好的hash算法应该有什么特点:首先效率要高,对长文本也能高效的计算出hash值;

不能根据hash值逆推出来原文;散列度较高输入有一点不同,得到的hash值就不同;极可能分散;

static final int hash(Object key) {
        int h;
        //将hashcode的高16位参与运算 防止散列
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

Node中的hash值不是key字段的hashcode值,而是key的hashcode经过二次hash后得到的结果hashcode的高16位与低16位异或操作后得到的

原因:因为大多数使用的hashmap的长度都不是很大,因此在进行寻址操作的时候(table.length - 1) & hash用的大多数都是低16位,因此将让hashcode的高16位也参与运算,减少hash冲突

JDK8链表 数组 红黑树

hashmap里面存储的元素是Node类型,里面包括key value hash next

3.创建hashmap默认长度为16

第一次put数据的时候会进行hashmap的创建,默认长度为16,负载因子为0.75,第一次扩容阈值为12

4.链表转化为红黑树的条件是,链表长度到达8,并且散列表数组的长度到达64,否则的话,就算链表长度到达8,也不会转化为红黑树,只会触发扩容操作resize();

put操作

首先都是进行hash算法,计算出具体的hash值,然后再根据寻址算法,计算出具体的桶位。

计算出具体的桶位后,分4种情况1.桶位没有元素 则直接将元素插入进去即可

2.桶位有元素但是没有形成链表(只有一个元素),此时需要将元素与要插入的元素key进行比较,如果相同则直接替换value,并且返回oldvalue

 3.桶位元素形成链表,遍历链表,对每一个节点,都进行key的比较,如果相同则发生和2相同的情况,如果不同则将元素插入链表尾结点,并且进行判断,链表长度是否达到8,如果达到8则需要进行树化操作

 4.桶位链表已经转化为红黑树,红黑树的插入操作,先找父节点,第一种是一直向下探测,直到找到左子树或者右子树为空,说明整个树中没有发现key相同的节点,此时节点就是插入节点的父节点,将当前节点插入到父节点的左子树或者右子树,根据插入节点的hash大小判断是左子树还是右子树,插入后有可能会打破平衡,需要平衡算法。第二种是,探测过程中找到key相同的节点,则直接返回该节点,然后进行替换操作。

红黑树特点

1.根节点为黑

2.叶子节点为黑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值