一、HashMap结构
大家都知道在JDK7中HashMap是用数组+链表的方式存储元素的。
二、初始化
HashMap的构造器有4个,其中三个是以容量(initialCapacity,容量是用来计算数组table的大小的)和负载因子(loadFactor)为参数,另外一个构造器是以Map为参数。无参构造器调用的是参数为容量和负载因子的构造器,默认容量为16,负载因子为0.75f。默认的阈值(threshold)为容量大小。
public HashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
threshold = initialCapacity;
init();
}
三、添加元素
当没有元素的时候,会先根据threshold对其膨胀(inflateTable),膨胀的作用就是新建一个长度适当的数组。数组的长度计算逻辑是:如果参数值toSize大于等于最大容量2的30次方,则长度为2的30次方,否则返回大于或等于toSize的最小的2的N次方的数。例如,toSzie是7,则长度就会为8,刚好是2的3次方。
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);

本文详细介绍了Java HashMap的内部结构,包括其数组+链表的存储方式,以及初始化、添加元素、扩容和转移元素的过程。特别地,文章通过示例代码解释了在多线程环境下,HashMap扩容可能导致的环形链表问题,分析了其原因在于头插法扩容导致的链表顺序反转。
最低0.47元/天 解锁文章
84

被折叠的 条评论
为什么被折叠?



