1.LinkedHashMap
LinkedHashMap是带链表的HashMap,所以LinkedHashMap是有序的,它作为HashMap的扩展,改变了HashMap无序的特征。LinkedHashMap使用了一个双向链表来维护key-value对的次序,该链表维护了map的迭代顺序,该迭代顺序和key-value对的插入顺序保持一致。
LinkedHashMap的数据结构图:
对于LinkedHashMap而言,它继承与HashMap、底层使用哈希表与双向链表来保存所有元素。其基本操作与父类HashMap相似,它通过重写父类相关的方法,来实现自己的链接列表特性。根据链表中元素的顺序可以分为:按插入顺序的链表和按访问顺序(调用get方法)的链表。
LinkedHashMap定义了排序模式accessOrder,该属性为boolean型变量,对于访问顺序,为true;对于插入顺序,则为false。
当有新元素加入Map的时候会调用Entry的addEntry方法,会调用removeEldestEntry方法,这就是实现LRU元素过期机制的地方,默认的情况下removeEldestEntry方法只返回false表示元素永远不过期。
2.LinkedHashMap用法
HashMap<String,String> map = new LinkedHashMap<String, String>(5, 0.5f, true) {
@Override
protected boolean removeEldestEntry( Map.Entry<String, String> eldest){
if(size() > 5){
return true;
}
return false;
}
};
map.put("a", "a");
map.put("b", "b");
map.put("c", "c");
map.put("d", "d");
map.put("e", "e");
map.put("c", "c");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.print(entry.getValue() + ", ");
}
System.out.println();
map.get("b");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.print(entry.getValue() + ", ");
}
System.out.println();
map.put("f", "f");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.print(entry.getValue() + ", ");
}
System.out.println();
打印结果:
a, b, d, e, c,
a, d, e, c, b,
d, e, c, b, f,
可见最新加入的或者最近get过的就会往最后放,如果put数目大于max,就会把头上那个去掉,然后f加到最后,其他往前移。
所以说不只是put,get也会把Entry往后方,越往后的说明最近才访问过的,越往前的说明最近最少访问的,这就实现了一个