我们都站在巨人的肩膀上
1.HashMap源码
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
{
// 默认的初始容量
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
// 最大容量
static final int MAXIMUM_CAPACITY = 1 << 30;
// 默认加载因子,即当 元素个数 超过 容量长度的0.75倍 时,进行扩容
static final float DEFAULT_LOAD_FACTOR = 0.75f;
//共享空表
static final Entry<?,?>[] EMPTY_TABLE = {};
// 这个表调整时必须是原先的两倍
transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;
// 容量
transient int size;
// 下一次的容量规则为(容量*负载因数)
// 在创建表时,如果table == EMPTY_TABLE 这是初始容量
int threshold;
// 哈希表的加载因子
final float loadFactor;
// hash表被修改的次数
transient int modCount;
// map 的最大值临界值
static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = Integer.MAX_VALUE;
// 这个方法需要在JVM启动之后执行
private static class Holder {
// 超过表容量使用hash散列
static final int ALTERNATIVE_HASHING_THRESHOLD;
static {
// AccessController.doPrivileged 意思是这个是特别的,不用做权限检查。
// 获取jdk内置的阀值
String altThreshold = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"jdk.map.althashing.threshold"));
// 设置当前阀值
int threshold;
try {
threshold = (null != altThreshold)
? Integer.parseInt(altThreshold)
: ALTERNATIVE_HASHING_THRESHOLD_DEFAULT;
// 如果是-1禁止用散列
if (threshold == -1) {
threshold = Integer.MAX_VALUE;
}
if (threshold < 0) {
throw new IllegalArgumentException("value must be positive integer.");
}
} catch(IllegalArgumentException failed) {
throw new Error("Illegal value for 'jdk.map.althashing.threshold'", failed);
}
ALTERNATIVE_HASHING_THRESHOLD = threshold;
}
}
// 解决hash冲突,如果是0禁止用散列
transient int hashSeed = 0;
// 指定初始大小和负载因子的构造函数
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();
}
// 指定初始化大小的构造函数,默认负载因子为0.75
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
// 无参构造,默认容量大小为16,负载因子为0.75
public HashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
// 构造一个与指定map相同关系的hashmap
public HashMap(Map<? extends K, ? extends V> m) {
// Math.max(...)计算大小
// 默认负载因子为0.75
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
// 初始化hashmap
inflateTable(threshold);
// 将map转hashmap
putAllForCreate(m);
}
// 这个方法是用来返回大于等于最接近number的2的冪数
private static int roundUpToPowerOf2(int number) {
// assert number >= 0 : "number must be non-negative";
return number >= MAXIMUM_CAPACITY
? MAXIMUM_CAPACITY
// 用来返回小于等于最接近number的2的冪数
: (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1;
}
// 初始化该表
private void inflateTable(int toSize) {
// 初始化容量大小
int capacity = roundUpToPowerOf2(toSize);
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
table = new Entry[capacity];
initHashSeedAsNeeded(capacity);
}
// internal utilities
// 重写入口
void init() {
}
// 初始化散列掩码值。我们推迟初始化直到真的需要它
final boolean initHashSeedAsNeeded(int capacity) {
boolean currentAltHashing = hashSeed != 0;
boolean useAltHashing = sun.misc.VM.isBooted() &&
(capacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD);
boolean switching = currentAltHashing ^ useAltHashing;
if (switching) {
hashSeed = useAltHashing
? sun.misc.Hashing.randomHashSeed(this)
: 0;
}
return switching;
}
//检索对象的散列码和补充哈希函数适用于散列结果,防范质量差哈希函数。
//这是至关重要的,因为HashMap使用哈希表2的幂长度,否则遇到的碰撞在低比特hashcode不同。
//注意:零键总是映射到散列0,因此索引0。
final int hash(Object k) {
int h = hashSeed;
// 如果hashSeed不等于0则可以使用hash函数
if (0 != h && k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}
h ^= k.hashCode();
// 此功能确保不同,只有不断的倍数在每一位哈希码有有限数量的碰撞(约8在默认加载因子)。
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
// 返回哈希值的索引
static int indexFor(int h, int length) {
// length必须为非0、2的幂
return h & (length-1);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
// 根据key获取value
public V get(Object key) {
// key为null时,hashmap定义了返回key==null 的方法。hashmap允许存在多个key为null的映射
if (key == null)
return getForNullKey();
// null == entry的话,返回null,否则返回value
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
// key==null时,或者返回值
private V getForNullKey() {
// size==0则返回null
if (size == 0) {
return null;
}
// size!=0,返回null==key的value
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null)
return e.value;
}
return null;
}
// 如何key存在,则返回true
public boolean containsKey(Object key) {
return getEntry(key) != null;
}
// 返回指定key的实例
final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
// 返回条件:1.哈希值必须相同,2.key必须相同
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
// 如果key存在则替换该旧值
public V put(K key, V value) {
// 如果table为空表则初始化该表
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
// 如果key为null,则设置key为null的value值
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
// 如果hash值相同并key相同,则替换值
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
// 记录操作次数
modCount++;
// 添加实例
addEntry(hash, key, value, i);
return null;
}
// 替换key为null 的value值
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
// 这里只是调用方法,这里不对表进行调整容量和检查等等,只是创建不是添加
private void putForCreate(K key, V value) {
int hash = null == key ? 0 : hash(key);
int i = indexFor(hash, table.length);
// 这里永远不会发生克隆和反序列化,如果输入是一个有序的map,输出不一定与排序顺序一致
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
e.value = value;
return;
}
}
createEntry(hash, key, value, i);
}
// 输入一个map,进行创建
private void putAllForCreate(Map<? extends K, ? extends V> m) {
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
putForCreate(e.getKey(), e.getValue());
}
// 调整大小,必须是比之前容量要大,当map容量达到阀值时调用,MAXIMUM_CAPACITY不用来调整大小,用Integer.MAX_VALUE进行调整
void resize(int newCapacity) {
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
// 如果旧值等于map容量最大值,则用Integer.MAX_VALUE扩容
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
}
Entry[] newTable = new Entry[newCapacity];
// 转移当前表所有的条目
transfer(newTable, initHashSeedAsNeeded(newCapacity));
table = newTable;
// 设置阀值
threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
}
// 转移当前表所有的条目
void transfer(Entry[] newTable, boolean rehash) {
int newCapacity = newTable.length;
for (Entry<K,V> e : table) {
while(null != e) {
Entry<K,V> next = e.next;
if (rehash) {
e.hash = null == e.key ? 0 : hash(e.key);
}
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
}
}
}
// 替换当前所有映射(key/value)
public void putAll(Map<? extends K, ? extends V> m) {
// m为空则不做任何操作
int numKeysToBeAdded = m.size();
if (numKeysToBeAdded == 0)
return;
// table为空表时,则初始化表
if (table == EMPTY_TABLE) {
inflateTable((int) Math.max(numKeysToBeAdded * loadFactor, threshold));
}
// 如果当前map的容量大于阀值则进行一个保守计算,进行扩容
if (numKeysToBeAdded > threshold) {
// 目标容量
int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);
// 如果目标容量大于map最大容量,则赋值为map最大容量
if (targetCapacity > MAXIMUM_CAPACITY)
targetCapacity = MAXIMUM_CAPACITY;
// 如果当前table的容量小于目标容量,则进行扩容
int newCapacity = table.length;
while (newCapacity < targetCapacity)
newCapacity <<= 1;
// 如果扩容后的容量大于当前table的容量则进行调整
if (newCapacity > table.length)
resize(newCapacity);
}
// 插入值
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
put(e.getKey(), e.getValue());
}
// 根据key删除映射,如果实例不存在则返回null,如果存在则返回实例
public V remove(Object key) {
Entry<K,V> e = removeEntryForKey(key);
return (e == null ? null : e.value);
}
// 根据key删除实例并返回该实例
final Entry<K,V> removeEntryForKey(Object key) {
if (size == 0) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
Entry<K,V> prev = table[i];
Entry<K,V> e = prev;
while (e != null) {
// 记录next
Entry<K,V> next = e.next;
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
// 记录操作次数
modCount++;
// 容量-1
size--;
// 如果为头节点,则直接赋值为next,否则将prev.next = next
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
return e;
}
prev = e;
e = next;
}
return e;
}
// 根据一个实例删除
final Entry<K,V> removeMapping(Object o) {
if (size == 0 || !(o instanceof Map.Entry))
return null;
Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
Object key = entry.getKey();
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
Entry<K,V> prev = table[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
if (e.hash == hash && e.equals(entry)) {
modCount++;
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
return e;
}
prev = e;
e = next;
}
return e;
}
// 删除所有map映射
public void clear() {
modCount++;
// 将table设置为空
Arrays.fill(table, null);
// 将长度制设置为0
size = 0;
}
// 检查是否存在指定value
public boolean containsValue(Object value) {
if (value == null)
return containsNullValue();
Entry[] tab = table;
for (int i = 0; i < tab.length ; i++)
for (Entry e = tab[i] ; e != null ; e = e.next)
if (value.equals(e.value))
return true;
return false;
}
// 检查是否存在值为null的value
private boolean containsNullValue() {
Entry[] tab = table;
for (int i = 0; i < tab.length ; i++)
for (Entry e = tab[i] ; e != null ; e = e.next)
if (e.value == null)
return true;
return false;
}
// 克隆一个新map,key/value并不克隆
public Object clone() {
HashMap<K,V> result = null;
try {
result = (HashMap<K,V>)super.clone();
} catch (CloneNotSupportedException e) {
// assert false;
}
// table不为空则初始化表
if (result.table != EMPTY_TABLE) {
result.inflateTable(Math.min(
(int) Math.min(
size * Math.min(1 / loadFactor, 4.0f),
// we have limits... 最大限制为map的最大容量
HashMap.MAXIMUM_CAPACITY),
table.length));
}
result.entrySet = null;
result.modCount = 0;
result.size = 0;
result.init();
result.putAllForCreate(this);
return result;
}
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry e = (Map.Entry)o;
Object k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
Object v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
// Entity hashCode计算方法,key.hashCode^value.hashCode
public final int hashCode() {
return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
}
public final String toString() {
return getKey() + "=" + getValue();
}
// 替换值时,调用次方法
void recordAccess(HashMap<K,V> m) {
}
// 删除值时,调用次方法
void recordRemoval(HashMap<K,V> m) {
}
}
// 添加一个新实例到map中,并且检查扩容
// 子类可重写此方法
void addEntry(int hash, K key, V value, int bucketIndex) {
// size大于阀值并且该值不为空,则进行调整
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
// 计算新下标
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}
// 创建实例
// 子类可重写此方法
void createEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
size++;
}
// 迭代器
private abstract class HashIterator<E> implements Iterator<E> {
Entry<K,V> next; // next entry to return
int expectedModCount; // For fast-fail
int index; // 当前的位置
Entry<K,V> current; // 当前的实例
HashIterator() {
// 当前map的操作次数
expectedModCount = modCount;
// 如果map不为空,则将当前table赋值给新数组,并确定下一个实例是否为空
if (size > 0) { // advance to first entry
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
}
public final boolean hasNext() {
return next != null;
}
final Entry<K,V> nextEntry() {
// 修改次数要保持一致
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Entry<K,V> e = next;
// 实例不能为空
if (e == null)
throw new NoSuchElementException();
// 如果next为空,则将现有的table赋值给新数组,并确定下一个实例是否为空
if ((next = e.next) == null) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
// 赋值给当前实例
current = e;
return e;
}
public void remove() {
// 当前实例不能为null
if (current == null)
throw new IllegalStateException();
// 操作次数必须一致才能执行删除操作
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Object k = current.key;
// 先将当前实例设置为空
current = null;
// 调用hashmap删除方法
HashMap.this.removeEntryForKey(k);
// 操作次数保持一致
expectedModCount = modCount;
}
}
// value迭代器
private final class ValueIterator extends HashIterator<V> {
public V next() {
return nextEntry().value;
}
}
// key迭代器
private final class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}
// 实例迭代器,继承HashIterator
private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}
// 子类可重写一下方法,改变行为
Iterator<K> newKeyIterator() {
return new KeyIterator();
}
Iterator<V> newValueIterator() {
return new ValueIterator();
}
Iterator<Map.Entry<K,V>> newEntryIterator() {
return new EntryIterator();
}
// Views
private transient Set<Map.Entry<K,V>> entrySet = null;
// 由于是set,所以是无序序列
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}
// 继承set抽象类,所以keySet有AbstractSet的特征,操作基本是hashmap的操作,但是没有add,addAll等添加方法
private final class KeySet extends AbstractSet<K> {
public Iterator<K> iterator() {
return newKeyIterator();
}
public int size() {
return size;
}
// keySet中contains判断,仅仅判断key是否存在
public boolean contains(Object o) {
return containsKey(o);
}
// keySet中remove,仅仅判断key去删除
public boolean remove(Object o) {
return HashMap.this.removeEntryForKey(o) != null;
}
public void clear() {
HashMap.this.clear();
}
}
// 获取hashmap value集合
public Collection<V> values() {
Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));
}
// 继承AbstractCollection,所以具备父类特征,操作也是hashmap的操作方法
private final class Values extends AbstractCollection<V> {
public Iterator<V> iterator() {
return newValueIterator();
}
public int size() {
return size;
}
// 仅仅判断value是否存在
public boolean contains(Object o) {
return containsValue(o);
}
public void clear() {
HashMap.this.clear();
}
}
// 由于是set集合,所以是无序集合
public Set<Map.Entry<K,V>> entrySet() {
return entrySet0();
}
// 不为空的情况下返回EntrySet的实例
private Set<Map.Entry<K,V>> entrySet0() {
Set<Map.Entry<K,V>> es = entrySet;
return es != null ? es : (entrySet = new EntrySet());
}
// 继承AbstractSet,具备父类特征,同事是无序序列
private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
return newEntryIterator();
}
public boolean contains(Object o) {
// 如果不是Entry类型,则返回false
if (!(o instanceof Map.Entry))
return false;
Map.Entry<K,V> e = (Map.Entry<K,V>) o;
// 根据key查找实例
Entry<K,V> candidate = getEntry(e.getKey());
return candidate != null && candidate.equals(e);
}
public boolean remove(Object o) {
return removeMapping(o) != null;
}
public int size() {
return size;
}
public void clear() {
HashMap.this.clear();
}
}
// 写入流
private void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
// 写入阀值,哈希因子,和隐藏信息
s.defaultWriteObject();
// 写入一些数据
// 如果table为空表,则随机写入2的幂数
if (table==EMPTY_TABLE) {
s.writeInt(roundUpToPowerOf2(threshold));
// 否则写入table表长度
} else {
s.writeInt(table.length);
}
// 写入size
s.writeInt(size);
// 写入key和value
if (size > 0) {
for(Map.Entry<K,V> e : entrySet0()) {
s.writeObject(e.getKey());
s.writeObject(e.getValue());
}
}
}
private static final long serialVersionUID = 362498820763181265L;
// 读出流
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException
{
// 读出阀值、哈希因子和一些隐藏信息
s.defaultReadObject();
// 哈希因子不能小于0,或者必须是数字
if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
throw new InvalidObjectException("Illegal load factor: " +
loadFactor);
}
// 设置其他的需要的字段
table = (Entry<K,V>[]) EMPTY_TABLE;
// 读出一些数据
s.readInt(); // ignored.
// 读取map数量,不能小于0
int mappings = s.readInt();
if (mappings < 0)
throw new InvalidObjectException("Illegal mappings count: " +
mappings);
// 设置容量
int capacity = (int) Math.min(
mappings * Math.min(1 / loadFactor, 4.0f),
// we have limits...
HashMap.MAXIMUM_CAPACITY);
// 如果map不为空泽初始化表
if (mappings > 0) {
inflateTable(capacity);
// 否则将容量作为阀值
} else {
threshold = capacity;
}
init(); // 子类重新此方法
// 读取key/value,并作映射关系
for (int i = 0; i < mappings; i++) {
K key = (K) s.readObject();
V value = (V) s.readObject();
putForCreate(key, value);
}
}
// These methods are used when serializing HashSets
int capacity() { return table.length; }
float loadFactor() { return loadFactor; }
}