一、HashMap 的长度为什么是 2 的 N 次方

为了能让HashMap存数据和取数据的效率高,尽可能地减少hash值碰撞,也就是说尽量把数据能平均分配,每个链表或者红黑树长度尽量相等。

取余(%)操作中,如果除数是2的幂次,则等价于与其除数减一的与(&)操作。

即:hash%length == hash &(length -1),这个等式成立的前提是length是2的n次方。

采用二进制位操作&相对于%能够大大提高运算效率。

二、HashMap 与 ConcurrentHashMap 的异同

1、都是key-value形式存储数据;

2、HashMap线程不安全,ConcurrentHashMap是JUC下的线程安全的;

3、HashMap底层数据结构是数组+链表(JDK1.8之前)。JDK1.8之后是数组+链表+红黑树。当链表中元素个数达到8的时候,链表的查询速度不如红黑树快,链表会转为红黑树;

4、HashMap初始数组大小为16(默认),当出现扩容时,以0.75*数组大小的方式进行扩容;

5、ConcurrentHashMap在JDK1.8之前是采用分段锁来实现的Segment+HashEntry,Segment数组大小默认是16,2的n次方;JDK1.8之后采用Node+CAS+Synchronized来保证并发安全的实现