HashMap:
底层是由数组 + 链表组成。
数组是Entry类数组,Entry中包含key、value、next。
数组长度默认是16。
当往HashMap中put值时,会将 key的哈希值 和 (Entry[]长度-1) 进行与运算。
假设得到的是0,如果Entry[0]该位置已有A,则将Entry[0]赋值为后插入的B,然后将B的next指向原来的A。
随着HashMap中值的逐步增多,Entry[]会以一定的规则加长长度。
为什么默认长度是16,且一般创建HashMap对象的时候,构建参数一般都是填的2的N次方。
假设Entry[]长度是15,那么Entry[]长度-1 = 14,转换成二进制就是 1110, 那么进行与运算,最后一位无论是0还是1进行与运算都是0,会导致index=14的几率更大,造成分布不均衡。
另外在JDK1.8中,如果链表的长度超过8,会自动将其转换成红黑树。
HashMap默认的扩容因子是0.75,即HashMap中实际存放的内容超过 Entry[]长度*0.75,那么会自动进行扩容。
如果并发高的情况,我们一般不会使用HashTable,而是采用效率更高的ConcurrentHashMap。
ConcurrentHashMap在JDK1.8后没有采用以前的Segment(桶锁),而是采用CAS算法(CompareAndSwap)。