一.什么是HashMap
HashMap是一种数据结构,它根据键的HashCade值,可以找到对应的值。HashMap查找值非常快,并且运行空值存在。HashMap在JDK1.7版本之前的存储结构是数组+单链表,在JDK1.8版本存储结构变为数组+单链表+红黑数。如下图所示
二.HashMap源码解析
2.1HsahMap的继承结构,属性,内部类和构造方法
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
HashMap继承于AbstractMap,继承的接口有Map,Cloneable,Serializable.
private static final long serialVersionUID = 362498820763181265L;
版本号
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
默认初始容量为16。
static final int MAXIMUM_CAPACITY = 1 << 30;
最大容量2的30次幂。
static final float DEFAULT_LOAD_FACTOR = 0.75f;
默认加载因子0.75.
static final int TREEIFY_THRESHOLD = 8;
链表转红黑树的阈值为8。
static final int UNTREEIFY_THRESHOLD = 6;
红黑树转链表的阈值为6.
static final int MIN_TREEIFY_CAPACITY = 64;
转红黑树,数组table的最小长度为64.
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() { return key; }
public final V getValue() { return value; }
public final String toString() { return key + "=" + value; }
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
}
链表节点继承于Entry。提供了三个对节点操作的方法。
transient Node<K,V>[] table;
table数组
transient Set<Map.Entry<K,V>> entrySet;
enterySet链表
transient int size;
int threshold;
阈值
final float loadFactor;
加载因子
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);