首页 > 其他分享 >HashMap底层原理与扩容机制

HashMap底层原理与扩容机制

时间:2023-11-30 17:23:19浏览次数:29  
标签:扩容 TREEIFY hash HashMap tab Node key null 底层


1.7 数组 + 链表
1.8 数组 + (链表 | 红黑树)

JAVA 1.8 之后hashmap 树化规则

HashMap里面定义了一个常量TREEIFY_THRESHOLD = 8,当链表长度超过树化阈值 8 时,
先尝试调用resize()方法进行扩容来减少链表长度,如果数组容量已经 >=64(MIN_TREEIFY_CAPACITY),
才会进行树化,Node节点转为TreeNode节点(TreeNode也是HashMap中定义的内部类)。
如下代码所示:在计算当前key时候,遍历当前桶 节点Node数binCount,如果binCount大于TREEIFY_THRESHOLD 8,则调用treeifyBin 尝试扩容。
treeifyBin 方法中 如果桶数组长度tab.length小于MIN_TREEIFY_CAPACITY 64,则直接桶数组扩容;
如果 桶数组长度tab.length大于MIN_TREEIFY_CAPACITY 64 则Node节点转为TreeNode(红黑树)节点
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
...
int binCount = 0;
if ((first = tab[i = (n - 1) & hash]) != null) {
if (first instanceof TreeNode)
old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key);
else {
Node<K,V> e = first; K k;
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
old = e;
break;
}
++binCount;
} while ((e = e.next) != null);
}
}
...
tab[i] = newNode(hash, key, v, first);
if (binCount >= TREEIFY_THRESHOLD - 1)
treeifyBin(tab, hash);
}

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;
}

标签:扩容,TREEIFY,hash,HashMap,tab,Node,key,null,底层
From: https://www.cnblogs.com/adamli/p/17867836.html

相关文章

  • HashMap
    HashMap是一种基于哈希表的数据结构,它通过使用散列算法来存储和检索数据,因此在查找速度上非常高效。在具体格式上,HashMap在JDK1.8之前采用的是数组+链表的格式,而在JDK1.8之后则采用了数组+链表+红黑树的结构。更具体地,HashMap是通过一个公式:index=hash&(table.length-1),来确定元素......
  • go数据类型-slice底层
    切片的底层数据结构有上篇string为基础了,能猜到slice肯定也有一个对应的struct。在runtime的slice.go中typeslicestruct{ arrayunsafe.Pointer lenint capint}切片的本质是对数组的引用len表示当前已经存储的个数,cap表示容量。切片的创建......
  • go基础数据类型 - string的底层
    先上一段代码:funcmain(){ content:="长沙boy" content1:="boy" fmt.Printf("content:%d\n",unsafe.Sizeof(content)) fmt.Printf("content1:%d\n",unsafe.Sizeof(content1))}打印的结果:content:16content1:16问题1、从这里......
  • sendevent、getevent解析及底层操作
    getevent实时获取触控事件getevent-lt/dev/input/event1-t时间-l文本显示状态记录示例//事件类型事件码事件值EV_ABSABS_MT_TRACKING_ID0000000fEV_ABSABS_MT_POSITION_X00002bbcEV_ABSABS_MT_POSITION_Y00001......
  • 面试官:为什么阿里不推荐使用 keySet() 遍历 HashMap?太叼钻了吧。。
    来源:https://juejin.cn/post/7295353579002396726Part1引言HashMap相信所有学Java的都一定不会感到陌生,作为一个非常重用且非常实用的Java提供的容器,它在我们的代码里面随处可见。因此遍历操作也是我们经常会使用到的。HashMap的遍历方式现如今有非常多种:使用迭代器(Iterator)......
  • 【linux常见问题】Aws机器磁盘在线扩容
    Aws机器磁盘在线扩容获取需求(adc机器磁盘扩容至50G--原磁盘:30G)aws控制台登录3、选择卷组4、修改卷组登录实例修改实际大小a、通过df-h查看磁盘目前大小目前磁盘大小(30G)b、通过lsblk查看存储卷的真实size以及分区情况--磁盘已扩容但并未实际纳入使用存储卷已经调整为50G其上只有......
  • Spring Data Redis切换底层Jedis 和 Lettuce实现
    1简介SpringDataRedis是SpringData系列的一部分,它提供了Spring应用程序对Redis的轻松配置和使用。它不仅提供了对Redis操作的高级抽象,还支持Jedis和Lettuce两种连接方式。可通过简单的配置就能连接Redis,并且可以切换Jedis和Lettuce两个连接方式。下面先来看看我们该如何使......
  • HashMap中怎么处理桶冲突?
    一、关键词HashMap桶冲突二:知识点--两种方法:1).闭散列法: 若桶的key经过hash算法计算得到的映射仇重复,则把这个value放置在距离原本位置最近的下一个空的映射地址中,需要保持负载因子(=已存储个数/空间大小)大于一定的值(数组法)。2).开散列法: 经过hash计算得到的桶映射相同,则......
  • 小程序框架底层原理:一次从小到大,从简单到复杂的深度解析
    小程序框架底层原理:一次从小到大,从简单到复杂的深度解析一、小程序框架概述小程序框架,一种轻量级、可扩展的前端开发框架,广泛应用于各种业务场景。它不仅提供了丰富的组件库和API接口,还具备跨平台、低功耗、易于集成等特点。本文将从小程序框架的底层原理出发,详细阐述其核心架构......
  • ConcurrentHashMap
    jdk1.8之后:syncronized+cashttps://blog.csdn.net/ThinkWon/article/details/102506447syncronized锁加到了链表上cas是没有hash冲突的时候,往数组插入元素时候用的。put元素的时候:首先对于每一个放入的值,首先利用spread方法对key的hashcode进行一次hash计算,由此来确定......