HashMap和ConcurrentHashMap
分类:
文章
•
2024-11-23 20:16:58
一.基本信息
1.结论
- hashmap默认大小是16,负载因子是0.75,当容量超过十二,调用resize()进行扩容,扩容后的大小是原来的2倍。
- hashmap是线程不安全的
- hashmap的大小是2的倍数
- jdk1.7数据结构是数组+链表,jdk1.8是数组+链表+红黑树。当链表的长度达到8同时数组长度到达64就会将链表转成红黑树,当链表长度小于6又会变成链表
- jdk1.7采用头插法,jdk1.8采用尾插法
2.常见问题
- 负载因子为什么是0.75,初始容量为什么是16?
- hashmap为什么是线程不安全,和hashtable有什么区别
- hashmap为什么扩容后是2的倍数
- hashmap插入数据的时候,进行hash运算为什么采用位运算
- hashmap为什么在jdk1.8之后采用尾插法?为什么引入红黑树?
- 链表长度大于8,链表转成红黑树,链表长度小于6又会由红黑树转成链表,为什么?
- hash冲突如何解决?
3.重要概念和变量
- DEFAULT_INITIAL_CAPACITY 默认初始化容量
- MAXIMUM_CAPACITY 最大容量 2 <<30
- DEFAULT_LOAD_FACTOR 默认负载因子
- TREEIFY_THRESHOLD 一个桶的树化阈值,默认为8
- UNTREEIFY_THRESHOLD 一个树的链表还原阈值,默认为6
- MIN_TREEIFY_CAPACITY hash表的最小树形化,默认64(当哈希表中的容量大于这个值时,表中的桶才能进行树形化
否则桶内元素太多时会扩容,而不是树形化
为了避免进行扩容、树形化选择的冲突,这个值不能小于 4 * TREEIFY_THRESHOLD)
- Node<K,V> 是hashmap中定义的静态内部类,实现了Map.Entry<K,V>。Node<K,V>中有四个变量,int hash和K key都是final修饰,V value 和Node<K,V> next
使用静态内部类,是为了方便调用,而不用每次调用里面的属性或者方法都需要new一个对象。
- transient 将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会被序列化
- Node<K,V>[] table 存储元素的数组
- Set<Map.Entry<K,V>> entrySet 将数据转换成set的另一种存储形式,这个
- 变量主要用于迭代功能
- size
- modCount
- loadFactor
- threshold
4.重要的方法汇总
- hash()传入key,返回int
- tableSizeFor
- 构造方法
- size()
- isEmtpy()
- get()
- put()
- resize()
- entrySet()返回的是Set<Map.Entry<K,V>>

二. 源码分析
三. 常见问题