LinkedHashMap
特点:
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
继承于HashMap null: 数据重复性: 安全性:hashtable\vector 底层数据结构:
不同点: HashMap:无法保证数据有序 LinkedHashMap保证数据有序
为什么LinkedHashMap能够做到数据有序(插入有序、访问有序)?
解释:LinkedHashMap有属性:accessOrder = false; false:插入有序 true 默认是accessOrder = false;//按照插入有序
LinkedHashMap的源码实现
继承关系
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
继承HashMap的父类,即拥有父类特征,实现Map接口,拥有map接口中的方法实现
属性
Entry<K,V> header;
//定义可一个entry类型的header属性
boolean accessOrder;
有序性标志: false:插入有序 true:访问有序
Entry<K,V> extends HashMap.Entry<K,V> {
继承HashMap的entry实体
属性有6个
entry {
final K key;
V value;
Entry<K,V> next;
int hash;
Entry<K,V> before;
Entry<K,V> after;
}
put添加元素的过程
/*父类HashMap的实现*/
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
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;
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;
}
/*LinkedHashMap的实现*/
void addEntry(int hash, K key, V value, int bucketIndex) {
super.addEntry(hash, key, value, bucketIndex);
// Remove eldest entry if instructed
Entry<K,V> eldest = header.after;
if (removeEldestEntry(eldest)) {
removeEntryForKey(eldest.key);
}
}
/*父类HashMap的实现*/
void addEntry(int hash, K key, V value, int bucketIndex) {
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);
}
/*LinkedHashMap的实现*/
void createEntry(int hash, K key, V value, int bucketIndex) {
HashMap.Entry<K,V> old = table[bucketIndex];
Entry<K,V> e = new Entry<>(hash, key, value, old);
table[bucketIndex] = e;
e.addBefore(header);
size++;
}
/*LinkedHashMap的实现*/
private void addBefore(Entry<K,V> existingEntry) {
after = existingEntry;
before = existingEntry.before;
before.after = this;
after.before = this;
}
通过源码解读,其元素添加和HashMap的实现是一致的
不同的处理是在数据顺序性处理上
LinkedHashMap的head节点初始化:
header = new Entry<>(-1, null, null, null);
header.before = header.after = header;
在处理过程中,始终获取header节点,
header节点的before节点的after指向当前节点
header节点的before指向当前节点
AccessOrder作用方法?插入有序/访问有序的处理
get() 获取元素的方法中有使用
AccessOrder=true时做处理
注意:仅处理before、after的指向流程
对原HashMap的数据+链表的关系没有改变;即数据hash索引位无影响,链表位置无影响