Java HashMap和HashSet源码
一: 先说说hashmap的数据结构
哈希表+数组+链表+红黑树
二:看下hashmap的成员
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //默认初始化数组的长度 static final int MAXIMUM_CAPACITY = 1 << 30; //最大数组长度 static final float DEFAULT_LOAD_FACTOR = 0.75f; //桶因子 static final int TREEIFY_THRESHOLD = 8; //链表装换成树的最小链表长度 static final int UNTREEIFY_THRESHOLD = 6; //树转换成链表的最大树元素个数 static final int MIN_TREEIFY_CAPACITY = 64; //链表转换成树的最小数组长度
/**
* The number of key-value mappings contained in this map.
*/
transient int size; //map的size
/**
* The next size value at which to resize (capacity * load factor).
*/
int threshold; //扩容阀值,capacity * load factor
三:向集合中添加元素的过程
1- size<threshold,直接插入元素;
size>threshold并且capacity <MIN_TREEIFY_CAPACITY,进行扩容;
size>threshold并且capacity >=MAXIMUM_CAPACITY,进入第二步;
2- 链表的长度小于TREEIFY_THRESHOLD,直接插入元素;
链表的长度大于TREEIFY_THRESHOLD并且capacity >MIN_TREEIFY_CAPACITY,链表转换为树;
注:删除元素时,满足树中元素小于UNTREEIFY_THRESHOLD时,会进行树转为链表。
四:hashSet实质上就是hashMap,只不过其值为Object
五:ConcurrentHashMap
ConcurrentHashMap 和 HashMap 思路是差不多的,但是因为它支持并发操作,所以要复杂一些。
整个 ConcurrentHashMap 由一个个 Segment 组成,Segment 代表”部分“或”一段“的意思,所以很多地方都会将其描述为分段锁。注意,行文中,我很多地方用了“槽”来代表一个 segment。
简单理解就是,ConcurrentHashMap 是一个 Segment 数组,Segment 通过继承 ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住的是一个 segment,这样只要保证每个 Segment 是线程安全的,也就实现了全局的线程安全。
java7的segment数组一旦初始化以后,它是不可以扩容的。
java8是可以进行扩容的。 具体太繁琐。
参考内容:http://www.importnew.com/28263.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!