HashMap结构及版本区别
1、HashMap:
继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。
是散列分布存储的,通过key/value结构实现。其中key和value都可以是null,是无序的。
2、HashMap的结构
2.1、jdk1.7采用 数组+ 单链表的数据结构
hashMap 在1.7的结构
hash表是一个数组,根据索引将条目存入hash表中,如果出现hash索引相同的时候,将会以链表的形式在同一个索引处储存多个条目,后来的条目存在在链表最后边(头插法)。
【什么是hashmap头插法:https://blog.csdn.net/styhm/article/details/111212508】
2.2、jdk1.8后,HashMap的结构是数组+链表+红黑树
从JAVA 7中得知,在查找元素时候,可以根据hash值快速定位到数组具体的下标,但是后面的操作需要顺着链表一个一个的比较下去才能找到所需值,时间复杂度取决于链表的长度,为O(n),为了降低这一部分处理的开销,在JAVA 8中,当链表中的元素超过8个之后,会将链表转换为红黑树,在这些位置进行查找的时候可降低时间复杂度 为O(logn)。当红黑树节点数小于6就会变成链表。
3、HashMap 初始容量与加载因子。
当HashMap实例化时会涉及初始化容量,初始化容量默认是16.
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 16;// 默认初始容量为16,必须为2的幂
当hash表中的条目数超过 容量 * 加载因子时,通过调用 rehash 方法(resize)将容量翻倍。
其中需要注意的是容量设置必须是2的整数次幂。那么为什么,必须是2的整数次幂呢?
hashmap中默认加载因子0.75
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
为什么加载因子默认是0.75,而不是1呢,这要从空间(hash容量)和时间(存入是否发生碰撞,取是否需要遍历链表)两个方面综合评价。从而得出的一个较为调优的值0.75
4、hashMap的hash是怎么计算的
hashmap怎么将给加入进来的元素散列分布在table表的各个位置的呢
参考文章https://blog.csdn.net/styhm/article/details/109778522
5、线程安全问题
https://blog.csdn.net/styhm/article/details/111227027
线程安全的HashMap可以用代替
ConcurrentHashMap map = new ConcurrentHashMap(32);