LinkedHashMap继承HashMap
LinkedHashMap底层数据存储算法依旧是hash算法,只是LinkedHashMap通过类似链表连接维持对元素插入顺序的存储
HashMap源码解读
一:新增的三个成员变量
- transient LinkedHashMap.Entry< K,V> head; // 指向头结点的地址
- transient LinkedHashMap.Entry< K,V> tail; // 指向尾节点的地址
- final boolean accessOrder; // accessOrder为true时,按访问顺序排序,false时,按插入顺序排序(默认false)
二: 重写HashMap中用于存储数据的内部类
/**
* 该类继承自HashMap.Node<K,V>
*/
static class Entry<K,V> extends HashMap.Node<K,V> {
// 用于存储前一个 后一个节点的地址
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
三:构造方法
/**
* 默认按照插入顺序排序
*/
public LinkedHashMap(int initialCapacity, floatloadFactor){
super(initialCapacity, loadFactor);
accessOrder = false;
}
/**
* 第三个参数为 true 意味着将按照访问顺序排序
* 既你访问过某个元素 将该元素所处位置置于链表尾端
*/
public LinkedHashMap(int initialCapacity,float loadFactor,
boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
四:get方法
public V get(Object key) {
Node<K,V> e;
// 若key为空 返回null
if ((e = getNode(hash(key), key)) == null)
return null;
// 若accessOrder 为true 执行
if (accessOrder)
// 将传入节点e放在链表最后
afterNodeAccess(e);
return e.value;
}
五:节点构造方法
/**
* 构造新节点方法
*/
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
LinkedHashMap.Entry<K,V> p =
new LinkedHashMap.Entry<K,V>(hash, key, value, e);
// 将新构造节点放在维持的链表最后
linkNodeLast(p);
return p;
}
源码阅读到此结束:以下是我对LinkedHashMap自己的一些理解
- HashMap使用哈希表来存储数据,并用拉链法来处理冲突。LinkedHashMap继承自HashMap,同时自身有一个链表,使用链表存储数据,不存在冲突。LinkedList和LinkedHashMap一样使用一个双向循环链表,但存储的上一个节点和一下一个节点的引用地址。所以HashMap和LinkedHashMap是Map。
- accessOrder 属性 默认为false,accessOrder为true时,取出一个数据将该数据放入链表末尾
//展示案例
LinkedHashMap<Integer, Object> map = new LinkedHashMap<Integer, Object>(16, 0.75F, true);
for (int i = 0; i < 20; i++) {
map.put(i, null);
}
map.keySet().forEach(e -> System.out.print(e + ","));
map.get(5);
map.get(6);
System.out.println();
map.keySet().forEach(e -> System.out.print(e + ","));
/**
* console
* 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
* 0,1,2,3,4,7,8,9,10,11,12,13,14,15,16,17,18,19,5,6,
*/