关于哈希表的一些整理
散列表也叫哈希表,这种数据结构提供了键(Key)和值(Value)的映射关系。
哈希表的底层结构是 数组+链表 / 数组+红黑树
因为每个对象都有属于自己的hashcode,所以可以根据hashcode通过一个哈希函数来计算获得对象的存储位置(即数组下标)。
但是数组的长度是有限的,存储的键值对(Entry)越来越多时,就会出现哈希冲突的情况。
解决哈希冲突主要有2中方法:(1)开放定址法(2)链地址法
开放定址法:发生哈希冲突时,继续寻找下一块未被占用的存储地址;
链地址法:把存在数组里的每个Entry对象同时也作为一个链表的头结点,发生冲突时就把新的Entry对象插入到对应的链表中即可。
在JDK1.8以后,当链表长度超过8时,哈希表结构就变为数组+红黑树。
在Java中,ThreadLocal采用了开放定址法,HashMap采用了链地址法。
当经过多次元素插入,哈希表达到一定饱和度时,发生哈希冲突的概率逐渐增大,这样相同数组下标位置下会形成很长的链表,这时候需要扩容。
对于HashMap,它有默认的初始容量(Capacity)16,和默认的加载因子(LoadFactor)0.75。
当HashMap的大小 size>=Capacity*LoadFacto r时,需要进行扩容。
扩容机制:
(1)创建一个新数组,长度为原来的2倍
(2)遍历原来的数组,把所有的Entry对象rehash到新数组中
学习参考资料:《漫画算法》