我们先抛出几个问题;带着问题来研究HashMap底层代码和提高HashMap的速度。问题如下:
1、为什么默认数组大小是16?
2、为什么扩容因子是0.75?
3、HashMap如何获取哈希值?
4、HashMap数组大小设置成7,9,11会怎么样?
5、HashMap底层结构是什么?
6、jdk1.7和jdk1.8版本优化了什么?
7、HashMap如何扩容?
HashMap默认参数说明
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 二进制1向左位移4位变成10000即2的4次幂 默认数组大小16
static final int MAXIMUM_CAPACITY = 1 << 30;
static final float DEFAULT_LOAD_FACTOR = 0.75f; //默认扩容因子 0.75
static final int TREEIFY_THRESHOLD = 8; //jdk1.8后,链表大小>=8时,启用红黑树
static final int UNTREEIFY_THRESHOLD = 6;
static final int MIN_TREEIFY_CAPACITY = 64; //jdk1.8后,数组大小>64时,启用红黑树
//jdk1.8红黑树的启用条件,链表>=8且数组大小>64时,启动红黑树。
//默认数组大小16;默认扩容因子0.75,当实际数据长度>数组大小的3/4时,开启扩容。
接下来,我们进行源码解析和部分测试结果的分析:
在测试环境下,进行以下几种HashMap构造的测试
Map<Integer, Integer> map = new HashMap<>();
Map<Integer, Integer> map1 = new HashMap<>(7);
Map<Integer, Integer> map2 = new HashMap<>(16);
Map<Integer, Integer> map3 = new HashMap<>(500000);
Map<Integer, Integer> map4 = new HashMap<>(10000000);
long start = Calendar.getInstance().getTimeInMillis();
for (int i = 0; i < 10000000; i++){
map.put(i, i);
//map1.put(i, i);
//map2.put(i, i);
//map3.put(i, i);
//map4.put(i, i);
}
long end = Calendar.getInstance().getTimeInMillis();
System.out.println(end - start);
//相同情况下,自定义大小与map数组大小一样的时候速度最快,其次是16,然后是最接近map数组大小,最后才是无参构造的。