这篇文章是LurCache源码分析的后续,如果想看LurCache源码分析,请转上一篇:《 避免OOM系列之(二)-------LruCache使用以及源码详细解析》。
我们先来看下继承关系:
我们看到LinkedHashMap 继承HashMap ,HashMap继承AbstractMap,如果你查看AbstractMap源码会发现,AbstractMap实现了Map,所有我们就从Map开始分析:
//map接口功能类
public interface Map {
//单个元素,接口功能类
public static interface Entry {
//是否相等
public boolean equals(Object object);
//获取key
public K getKey();
//获取value
public V getValue();
//获取哈希值
public int hashCode();
//设置值
public V setValue(V object);
};
//清空
public void clear();
//是否包含key
public boolean containsKey(Object key);
//是否包含这个值
public boolean containsValue(Object value);
//获取map中的元素结合(最核心的方法)
public Set> entrySet();
//是否相等
public boolean equals(Object object);
//获取元素
public V get(Object key);
//获取哈希code
public int hashCode();
//判断是否为空
public boolean isEmpty();
//获取key的集合(核心)
public Set keySet();
//存放元素
public V put(K key, V value);
//存放元素结合
public void putAll(Map extends K,? extends V> map);
//移除元素
public V remove(Object key);
//当前大小
public int size();
//获取当前值得集合(核心)
public Collection values();
}
public class HashMap extends AbstractMap implements Cloneable, Serializable {
//数组最小元素个数
private static final int MINIMUM_CAPACITY = 4;
//数组最大元素个数(2的30次方)
private static final int MAXIMUM_CAPACITY = 1 << 30;
//空数组,初始化元素个数(2)
private static final Entry[] EMPTY_TABLE
= new HashMapEntry[MINIMUM_CAPACITY >>> 1];
//当元素个数到达(3/4)数量是,扩展
static final float DEFAULT_LOAD_FACTOR = .75F;
//核心数组(table)
transient HashMapEntry[] table;
//key值为NULL的元素
transient HashMapEntry entryForNullKey;
//数组元素的个数
transient int size;
//元素修改的次数(包括添加修改删除更新)
transient int modCount;
//这三个字段,只有被用的时候才参数
//key集合
private transient Set keySet;
//元素集合
private transient Set> entrySet;
//值集合
private transient Collection values;
//capacity,必须是2的整数倍,
public HashMap(int capacity) {
if (capacity < 0) {
throw new IllegalArgumentException("Capacity: " + capacity);
}
if (capacity == 0) {
@SuppressWarnings("unchecked")
HashMapEntry[] tab = (HashMapEntry[]) EMPTY_TABLE;
table = tab;
threshold = -1; // Forces first put() to replace EMPTY_TABLE
return;
}
if (capacity < MINIMUM_CAPACITY) {
capacity = MINIMUM_CAPACITY;
} else if (capacity > MAXIMUM_CAPACITY) {
capacity = MAXIMUM_CAPACITY;
} else {
//如果capacity不是2的整数倍,就将他转成比capacity小的,2的整数倍值
capacity = Collections.roundUpToPowerOfTwo(capacity);
}
//扩大数组元素个数
makeTable(capacity);
}
//实现了Map.Entry接口
static class HashMapEntry implements Entry {
//key
final K key;
//value
V value;
//哈希值
final int hash;
//指向下一个元素
HashMapEntry next;
HashMapEntry(K key, V value, int hash, HashMapEntry next) {
this.key = key;
this.value = value;
this.hash = hash;
this.next = next;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final V setValue(V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
}
@Override public final boolean equals(Object o) {
if (!(o instanceof Entry)) {
return false;
}
Entry, ?> e = (Entry, ?>) o;
return Objects.equal(e.getKey(), key)
&& Objects.equal(e.getValue(), value);
}
@Override public final int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
@Override public final String toString() {
return key + "=" + value;
}
}
//添加元素
@Override public V put(K key, V value) {
//如果key为空,就将元素添加到entryForNullKey
if (key == null) {
return putValueForNullKey(value);
}
//得到key的hashcode
int hash = secondaryHash(key);
HashMapEntry[] tab = table;
//根据hash值计算出数组下标
int index = hash & (tab.length - 1);
//遍历元素,如果有这个元素,就直接返回
for (HashMapEntry e = tab[index]; e != null; e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
preModify(e);
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
// No entry for (non-null) key is present; create one
modCount++;
//如果元素的个数大于容量的3/4 .就扩展一倍容量,并且得到新的下标好
if (size++ > threshold) {
tab = doubleCapacity();
index = hash & (tab.length - 1);
}
//添加新的元素,如果对应下标有元素,就将新的元素添加到这个元素的后面,形成单向链表
addNewEntry(key, value, hash, index);
return null;
}
可以看到,table中的元素其实就是单向链表,那么现在的table数据结构就是:
//获取元素集合
public Set> entrySet() {
Set> es = entrySet;
return (es != null) ? es : (entrySet = new EntrySet());
}
//获取key集合
@Override public Set keySet() {
Set ks = keySet;
return (ks != null) ? ks : (keySet = new KeySet());
}
//获取value集合
@Override public Collection values() {
Collection vs = values;
return (vs != null) ? vs : (values = new Values());
}
//得到table中的所有元素,
private abstract class HashIterator {
int nextIndex;
HashMapEntry nextEntry = entryForNullKey;
HashMapEntry lastEntryReturned;
int expectedModCount = modCount;
HashIterator() {
if (nextEntry == null) {
HashMapEntry[] tab = table;
HashMapEntry next = null;
while (next == null && nextIndex < tab.length) {
next = tab[nextIndex++];
}
nextEntry = next;
}
}
public boolean hasNext() {
return nextEntry != null;
}
//得到table中的所有元素
HashMapEntry nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (nextEntry == null)
throw new NoSuchElementException();
HashMapEntry entryToReturn = nextEntry;
HashMapEntry[] tab = table;
HashMapEntry next = entryToReturn.next;
while (next == null && nextIndex < tab.length) {
next = tab[nextIndex++];
}
nextEntry = next;
return lastEntryReturned = entryToReturn;
}
public void remove() {
if (lastEntryReturned == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
HashMap.this.remove(lastEntryReturned.key);
lastEntryReturned = null;
expectedModCount = modCount;
}
}
//key迭代器类
private final class KeyIterator extends HashIterator
implements Iterator {
public K next() { return nextEntry().key; }
}
//value迭代器类
private final class ValueIterator extends HashIterator
implements Iterator {
public V next() { return nextEntry().value; }
}
//元素迭代器类
private final class EntryIterator extends HashIterator
implements Iterator> {
public Entry next() { return nextEntry(); }
}
//得到迭代器的方法
Iterator newKeyIterator() { return new KeyIterator(); }
Iterator newValueIterator() { return new ValueIterator(); }
Iterator> newEntryIterator() { return new EntryIterator(); }
//key集合的类
private final class KeySet extends AbstractSet {
//迭代器实现
public Iterator iterator() {
return newKeyIterator();
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
int oldSize = size;
HashMap.this.remove(o);
return size != oldSize;
}
public void clear() {
HashMap.this.clear();
}
}
//value集合的类
private final class Values extends AbstractCollection {
//迭代器实现
public Iterator iterator() {
return newValueIterator();
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(Object o) {
return containsValue(o);
}
public void clear() {
HashMap.this.clear();
}
}
//元素集合的类
private final class EntrySet extends AbstractSet> {
//迭代器实现
public Iterator> iterator() {
return newEntryIterator();
}
public boolean contains(Object o) {
if (!(o instanceof Entry))
return false;
Entry, ?> e = (Entry, ?>) o;
return containsMapping(e.getKey(), e.getValue());
}
public boolean remove(Object o) {
if (!(o instanceof Entry))
return false;
Entry, ?> e = (Entry, ?>)o;
return removeMapping(e.getKey(), e.getValue());
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void clear() {
HashMap.this.clear();
}
}
//头节点(双向链表)
transient LinkedEntry header;
//是否按照最近访问排序
private final boolean accessOrder;
public LinkedHashMap(
int initialCapacity, float loadFactor, boolean accessOrder) {
//初始化hashmap
super(initialCapacity, loadFactor);
init();
this.accessOrder = accessOrder;
}
//双向链表节点
static class LinkedEntry extends HashMapEntry {
//指向next元素
LinkedEntry nxt;
//指向前面元素
LinkedEntry prv;
LinkedEntry() {
super(null, null, 0, null);
nxt = prv = this;
}
LinkedEntry(K key, V value, int hash, HashMapEntry next,
LinkedEntry nxt, LinkedEntry prv) {
super(key, value, hash, next);
this.nxt = nxt;
this.prv = prv;
}
}
//添加新的元素
@Override void addNewEntry(K key, V value, int hash, int index) {
LinkedEntry header = this.header;
//获取最老的元素
LinkedEntry eldest = header.nxt;
//
if (eldest != header && removeEldestEntry(eldest)) {
remove(eldest.key);
}
//添加新元素,将header->pre指向新的元素
LinkedEntry oldTail = header.prv;
LinkedEntry newTail = new LinkedEntry(
key, value, hash, table[index], header, oldTail);
table[index] = oldTail.nxt = header.prv = newTail;
}
//添加key 为null的元素,并且添加到链表中
@Override void addNewEntryForNullKey(V value) {
LinkedEntry header = this.header;
// Remove eldest entry if instructed to do so.
LinkedEntry eldest = header.nxt;
if (eldest != header && removeEldestEntry(eldest)) {
remove(eldest.key);
}
// Create new entry, link it on to list, and put it into table
LinkedEntry oldTail = header.prv;
LinkedEntry newTail = new LinkedEntry(
null, value, 0, null, header, oldTail);
entryForNullKey = oldTail.nxt = header.prv = newTail;
}
@Override HashMapEntry constructorNewEntry(
K key, V value, int hash, HashMapEntry next) {
LinkedEntry header = this.header;
LinkedEntry oldTail = header.prv;
LinkedEntry newTail
= new LinkedEntry(key, value, hash, next, header, oldTail);
return oldTail.nxt = header.prv = newTail;
}
//获取元素
@Override public V get(Object key) {
/*
* This method is overridden to eliminate the need for a polymorphic
* invocation in superclass at the expense of code duplication.
*/
if (key == null) {
HashMapEntry e = entryForNullKey;
if (e == null)
return null;
if (accessOrder)
makeTail((LinkedEntry) e);
return e.value;
}
// Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
int hash = secondaryHash(key);
HashMapEntry[] tab = table;
for (HashMapEntry e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
K eKey = e.key;
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
if (accessOrder)
makeTail((LinkedEntry) e);
return e.value;
}
}
return null;
}
//将head ->pre指向最新操作的元素
private void makeTail(LinkedEntry e) {
// Unlink e
e.prv.nxt = e.nxt;
e.nxt.prv = e.prv;
// Relink e as tail
LinkedEntry header = this.header;
LinkedEntry oldTail = header.prv;
e.nxt = header;
e.prv = oldTail;
oldTail.nxt = header.prv = e;
modCount++;
}
//移除后,将引用全部去掉
@Override void postRemove(HashMapEntry e) {
LinkedEntry le = (LinkedEntry) e;
le.prv.nxt = le.nxt;
le.nxt.prv = le.prv;
le.nxt = le.prv = null; // Help the GC (for performance)
}
//是否包括value
@Override public boolean containsValue(Object value) {
if (value == null) {
for (LinkedEntry header = this.header, e = header.nxt;
e != header; e = e.nxt) {
if (e.value == null) {
return true;
}
}
return false;
}
// value is non-null
for (LinkedEntry header = this.header, e = header.nxt;
e != header; e = e.nxt) {
if (value.equals(e.value)) {
return true;
}
}
return false;
}
//清空,然后将引用去掉
public void clear() {
super.clear();
// Clear all links to help GC
LinkedEntry header = this.header;
for (LinkedEntry e = header.nxt; e != header; ) {
LinkedEntry nxt = e.nxt;
e.nxt = e.prv = null;
e = nxt;
}
header.nxt = header.prv = header;
}