一.Map接口的三个常用实现类 jdk1.8
类名 | 底层数据结构 | 线程是否安全 | 效率 | 增量值 |
HashMap | 链表加数组 | 线程不安全 | 效率都很快。 | 默认初始容量为0,第一次put后容量是16,每次扩容2倍。扩容因子是0.75 |
HashTable | 动态的数组结构 | 线程不安全 | 无论增删还是查询都非常慢 | 默认初始容量为0,第一次put后容量是16,每次扩容2倍。扩容因子是0.75,key不能为null |
LinkedHashMap | 继承hashmap, | 线程不安全 | 效率都很快。有序 | 使用hashmap特性 |
TreeMap | 二叉树 | 不安全 | 相对比较平衡 | 无 |
二.主要方法
hashmap维护的Node内部类
hash算法维护key 取模当前数组长度得到数组到下表
相同hash 得到到下表会存到同一个数组下标位置 ,里面维护一个Node链表数组,最新到存放到下标为0到位置,当维护长度达到8时候 结构变为二叉树结构
为何说HashMap是线程不安全的?
1、方法不是同步的
2、resize()方法在高并发的情况下,可能会引起死循环。
场景:resize()进行扩容时,需要rehash(),就是重新计算已有结点存放的位置。这个过程是非常耗费时间和空间的
问题关键:resize()方法中的transfer()方法进行位置重排时,因为不同的线程是对同一个数据块进行重排,所以才导致的问题