JDK1.8 HashMap源码解析 (扩容机制,null键,与1.7的区别等)

目录

hashmap 成员变量

hashmap支持null键吗?为什么?

当扩容的时候,所有元素都会重新计算hash值吗?

怎么减少扩容次数

为什么node数组的大小是2的n次?

1.8和1.7的区别

1.8为啥要用红黑树?

扩容机制不一样

在使用HashMap的过程中我们应该注意些什么问题?


补发一下积灰的文章。

hashmap 成员变量

  • DEFAULT_INITIAL_CAPACITY:默认初识表格的容量,值为 16,必须是 2 的 n 次方;
  • DEFAULT_LOAD_FACTOR:默认加载因子,值为 0.75;
  • loadFactor: 加载因子,可以通过构造函数设置 loadFactory;
  • threshold:阈值,当 hash 表的 size 大于这个值得时候,需要进行 resize 扩容操作,公式是 capacity * load factor;
  • entrySet:缓存 entrySet() 方法的数据,可以对键或者值进行遍历。
  • MIN_TREEIFY_CAPACITY:节点转换成红黑树需要的最少的表格容量,值是 64;
  • TREEIFY_THRESHOLD:判断节点是否需要转成红黑树节点,值是 8;
  • UNTREEIFY_THRESHOLD:判断是否需要调用 untreeify 方法,值是 6。

hashmap成员变量https://www.jianshu.com/p/c91dc4baf69f

hashmap支持null键吗?为什么?

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

hashmap支持null键,null key 对应的hash值就是0 存放在 第0个桶里面。

而其他key 需要先调用 hashcode 再和右移16位的值进行异或。

可以通过 tab[i = (n - 1) & hash]) 直接访问到该元素在table中处于的位置。

当扩容的时候,所有元素都会重新计算hash值吗?

不会,因为第一次put的时候已经计算过hash值了,在扩容的时候 只需要和 新的tablesize相与即可知道rehash的结果。

怎么减少扩容次数

如果提前知道自己的map中的元素数量的话,比如最多1024个元素,那么可以设置hashmap的容量为1024,也就是node数组的大小为1024,设置装载因子为1,这样即使所有的数据都存入hashmap,也不会触发扩容机制。

为什么node数组的大小是2的n次?

1 可以将hash值& len-1 得到对应的索引位置。

2 在扩容的时候只需要和 新的tablesize 相与即可知道rehash的结果。

1.8和1.7的区别

JDK8 中对算哈希值的哈希算法进行了简化以提高运算效率

1.8为啥要用红黑树?

因为链表的插入效率倒是高 头插但是查找效率低,所以用树去做优化, 提升查找和查询的效率。

扩容机制不一样

在使用HashMap的过程中我们应该注意些什么问题?

1. HashMap 的扩容机制是很影响效率的,所以如果事先能确定有多少个元素需要存储,那么建议在初始化HashMap 时对数组的容量也进行初始化,防止扩容。
2. HashMap 中使用了对象的 hashcode 方法,而且很关键,所以再重写对象的 equals 时建议一定要重写hashcode 方法。
3. 如果是用对象作为 HashMap key ,那么请将对象设置为 final ,以防止对象被重新赋值,因为一旦重新赋值其实就代表了一个新对象作为了 key ,因为两个对象的 hashcode 可能不同。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

trigger333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值