要探究的问题
- 1.HashMap的实现原理
- 2.拉链法导致的链表过深问题为什么不用二叉查找树代替,而选择红黑树?为什么不一直使用红黑树?
- 3.HashMap 的 table 的容量如何确定?loadFactor 是什么? 该容量如何变化?这种变化会带来什么问题?
- 4.为什么HashMap是线程不安全的以及如何规避
- SpareArray和ArrayMap
hash知识储备
存储key的地址和key之间需要建立映射关系,这个映射关系就是hash算法,也叫散列函数。通常情况下key1不等于key2,但会存在f(key1)=f(key2)的情况,这就是hash碰撞或者就hash冲突,解决方法有两种,开放寻址法和拉链法
开放寻址法
不断需要没有被占用的内存地址,存放key,这种方法需要的空间比较大
拉链法
key的内存地址不变,利用链表,不断插入后续的key,比较巧妙
HashMap
HashMap的数据结构通是数组、链表和红黑树,主要从三个方面put方法、resize、多线程不安全
put方法
先以Node<K,V>为元素存到数组里,数组的索引通过key的hash来计算,如果发生hash碰撞,则以链地址法链接到相应的链表里,如果阈值超过8,则转为红黑树
resize
超过最大容量,则触发扩容
扩容过程
- 遍历旧数组的元素,添加到新数组中,新数组length是旧数组的两倍
线程不安全
会发生无限循环,多线程并发操作应该使用ConcurrentHashMap,因为HashMap的结果输出是无序的,可以使用LinkedHashMap