1HashMap的存储结构在JDK1.8中 都做了哪些优化,Node[]数组
JDK7 数组加链表 JDK8 数组加树加红黑树 链表达到8时 并且容量达到64 会将链表,转成红黑树
static final int TREEIFY_THRESHOLD=8
static final MIN_TREEIFY_CAPACITY=64
//转换链表的临界值 当元素小于此值 会将红黑树转换成链表结构,
static final UNTREEIFY_THRESHOLD=6
红黑树有啥特点?
2Hashmap没有初始容量,默认是多少
static final int DEFAULT_INITIAL_CAPACITY=1<<4//aka 16
最大值为多少1073741824
static final int MAXIMUN_CAPACITY=1<<30
3加载因子 扩容的阈值
5什么时候链表转红黑树
链表达到8并且容量达到64时候 链表会转为红黑树
6为什么是2的幂
及时你构造函数时候 不传2的n次方,再后来的初始化方法中,也会强制变成2的n次方
让元素能够快速定位哈希桶,让Hash表元素分布均匀,减少哈希碰撞的几率
7若传入了一个初始化容量,则就是你传入的那个值吗?不一定,
是大于或等于你传入的那个值,离他最仅的那个2的幂的数
8put方法的流程
index:(table.length-1)&hash值 索引的计算公式,寻址公式。
9Node []数组,
Node的属性有哪些,分别干啥用的
final int hash;final K key ;V value; Node<K,V> next;
10get方法
三种情况:直接数组中命中,需要在树中找,需要在链表中找
11扩容相关
(1)扩容原因
a为了解决哈希冲突导致的链化影响查询效率的问题,扩容会缓解该问题
b容量不够也要扩容
(2)扩容多大
a若原来Node[]就是最大值,不扩
b oldCap左移一位,实现数据翻倍,并且赋值给newCap,newCap小于数组最大值限制,且扩容之前的阈值>=16
12初始化容量一上来就初始化,还是put才初始化?put时候才初始化,跟Arraylist类似
13hashmap线程安全么?不安全 有没有安全的 ConcurrentHashMap
14说一说ConcurrenHashMap原理?
15 HashTable vs HashMap hashtable比较古老,不用他,他线程安全。
因为hashtable如下 他直接锁方法,对整个数组加锁,力度过大
public synchronized V put(k key,V value)
16 ConcurrentHashMap
采用的是分段锁机制,通过synchronized锁定是代码块。
17 CopyOnWriteArrayList
写时复制容器 它在add方法中使用的是显示锁进行加锁, ReentrantLock