LinkedHashMap是一个维护插入或者访问顺序的HashMap, 是对HashMap的扩展.
它比HashMap多维护一个双向链表, 每个节点都是继承于HashMap.Node
LinkedHashMap的头尾节点:
代码语言:javascript复制transient LinkedHashMap.Entry head;
transient LinkedHashMap.Entry tail;
LinkedHashMap的节点类
代码语言:javascript复制static class Entry extends HashMap.Node{
Entrybefore, after;
Entry(int hash, K key, V value, Nodenext) {
super(hash, key, value, next);
}
}
链表节点的维护
在LinkedHashMap中并没有重写父类的插入或者查询等方法, 那链表中各节点是怎么维护的呢?
原来在HashMap的put(), get()等方法中是留有钩子的, 通过重写这几个钩子(方法), 达到链表维护的目的.
在执行插入, 查询以及删除数据的时候维护这个链表;
代码语言:javascript复制void afterNodeAccess(Nodep) { }
void afterNodeInsertion(boolean evict) { }
void afterNodeRemoval(Nodep) { }
类设计
从类的角度说, LinkedHashMap是继承HashMap的; 但是从代码的角度说, 两者也有互相依赖的地方.
1.HashMap专门留有3个方法为LinkedHashMap维护链表使用;
2.HashMap中的TreeNode是继承至LinkedHashMap.Entry, 并增加了父节点,左子节点,右子节点等指针.
代码语言:javascript复制static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
TreeNode<K,V> parent; // red-black tree links
TreeNode<K,V> left;
TreeNode<K,V> right;
TreeNode<K,V> prev; // needed to unlink next upon deletion
boolean red;
}
所以, 整体来看两个类是有一定耦合度的, 个人感觉这的设计是有瑕疵的.