环境:JDK 1.8
hashMap 与 hashTable 的区别 : hashMap 非同步,线程不安全。允许key,value为null
hashMap 与 arrayList的区别:
hashMap:查找快
arrayList:修改快
initial capacity(位运算,与运算): 默认为16,最大为2的30次方
Initial capacity = 想存的个数➗0.75 +1 (阿里巴巴手册建议:因为存在扩容问题)
(移位,按位或运算————设置的最大容量的最接近的2的n次幂)
resize(扩容):按原来 capacity 的两倍扩容,16——32
默认扩容:12开始扩容(16*0.75) 如果自己指定容量就不会*0.75(边界值)
Threshold=容量*负载因子(16*0.75)loadFactor:负载因子 ; Threshold:阈值
转换条件:
链表转红黑树的条件: 阈值大于8 ,并且数组长度大于等于64
红黑树转链表:阈值小于6
问题:
1.hash 冲突:(1.8之前使用链表解决;1.8之后使用链表+红黑树)
指的是调用hash()方法,计算的hash值一样。导致数组的索引一样。(这样的情况下,会先比较key值,再比较key的内容是否相同,相同就覆盖,不同就在链表后面添加元素)
转换条件:链表阈值大于8 & 数据长度大于等于64
2.集合底层都是2的n次幂 : 不然会导致hash冲突频率增加
tableSizeFor() : 进行了 或运算 和 位运算 —— index 取决于 hash 值
举例:init capacity = 5
3.tableSizeFor() cap 为什么要 -1:
防止传入的是2的n次幂,会翻倍
举例:init capacity = 8
4.为什么转换条件链表阈值为8 ?
泊松分布(pission)
5.*hash算法:
按位与和位运算 ,相当于hash%n ,因为取余效率低
6.put方法:
putVal():判断是红黑树还是链表进行的操作
7.resize():
1.初始化的时候
2.数组长度大于12(Threshold)
3. 数组长度小于64
*避免扩容:扩容后,数据重建
jdk1.8之后避免了rehash , 索引为旧的索引,或者是旧的索引+原来容量的位置(默认16)——————扩 容后的位置