LinkedHashMap基于链表的HashMap,继承自HashMap,所以HashMap有的功能它都有。
LinkedHashMap保存了元素的插入顺序,可以按照插入顺序遍历,也可以看作是FIFO访问顺序的实现。
同时,也可以设置保存访问顺序,按照最近最少访问的顺序保存元素, 也可以看作是LRU的实现。下文有实现LRU的方式
removeEldestEntry()默认实现是返回false,也就是不删除最旧的元素,实现LRU的时候需要重写此方法。
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
{
// Entry继承自HashMap的Node
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);
}
}
/**
* The head (eldest) of the doubly linked list.
* 双向链表的头,是最老的节点
*/
transient LinkedHashMap.Entry<K,V> head;
/**
* The tail (youngest) of the doubly linked list.
* 双向链表的尾,是最年轻的节点
*/
transient LinkedHashMap.Entry<K,V> tail;
/**
* The iteration ordering method for this linked hash map: <tt>true</tt>
* for access-order, <tt>false</tt> for insertion-order.
*
* true:按照访问顺序来遍历链表(LRU)
* false:按照插入顺序来遍历链表(FIFO)(默认)
*/
final boolean accessOrder;
}
// 实现LRU
class LRUCache extends LinkedHashMap {
final int cacheSize;
public LRUCache(int cacheSize) {
super((int)(cacheSize/0.75f) + 1, 0.75f, true);
this.cacheSize = cacheSize;
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
// 当插入的元素比设置的缓存大小更大时就要清楚最久的元素
return size() > cacheSize;
}
public static void lruCacheTest() {
LRUCache lruCache = new LRUCache(6);
lruCache.put("a",1);
lruCache.put("b",2);
lruCache.put("c",3);
lruCache.put("d",4);
lruCache.put("e",5);
lruCache.put("f",6);
Iterator iterator = lruCache.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
System.out.println(entry.getKey()+"--"+entry.getValue());
}
System.out.println(lruCache.get("c"));//key="c" 到队尾
lruCache.put("g",7);//key="g"到队尾,并删除key="a"
iterator = lruCache.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
System.out.println(entry.getKey()+"--"+entry.getValue());
}
/**
输出:
a--1
b--2
c--3
d--4
e--5
f--6
3
b--2
d--4
e--5
f--6
c--3
g--7*/
}
}
另一种实现方式:
final int cacheSize = 100;
Map<String, String> map = new LinkedHashMap<String, String>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
return size() > cacheSize;
}
};