LinkedHashMap继承了HashMap,它使用双链表将表中的所有节点连接在一起。
存储结构
1 | // 头结点 |
构造方法
1 | // accessOrder:是否按照访问顺序排序。若为false,表示按照插入顺序排序 |
创建节点
LinkedHashMap采用尾插法,每当创建新的节点后,都会将它链接到双链表的尾部。
1 | Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) { |
按键取值
1 | public V get(Object key) { |
当采用访问顺序时,调用了afterNodeAccess方法,将当前节点移动到链表尾部。
访问或更新以后
当执行put方法却发现key已经存在,或者调用get方法后,LinkedHashMap都将会执行如下方法:
1 | // 若采用访问顺序,则将当前节点移动到链表尾部 |
删除以后
每当执行删除操作后,LinkedHashMap都将执行如下方法:
1 | // 从双链表中删除该节点 |
插入以后
每当插入新元素后,LinkedHashMap都将执行如下方法:
1 | // 如果插入新元素后,需要删除最老的项 |
这里调用了removeEldestEntry方法,用于判断是否删除最老的项。
由于LinkedHashMap采用的是尾插法,所以双链表中最老的项就是头结点。
1 | protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { |
如果需要使用该功能,必须重写removeEldestEntry方法。
实现LRU
LRU(Least Recently Used,最近最少使用)算法,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。
当缓存容量达到上限时,在写入新数据之前需要删除最近最少使用的数据值,从而为新的数据值留出空间。
1 | class LRUCache<K, V> extends LinkedHashMap<K, V>{ |