java之LinkedHashMap讲解
HashMap大家都很了解,是一中比较常用的,也比较好用的集合,但是HashMap有一个顺序的问题,就是在对HashMap进行迭代访问时,添加的顺序和访问的顺序可能就不一样的,这个时候我们可以选择LinkedHashMap,
LinkedHashMap继承了HashMap,所以拥有和HashMap一样的功能;而且在此基础上有增加了一个双向链表来实现元素迭代的顺序,但是肯定会增加时间和空间的消耗,
LinkedHashMap和HashMap一样,也是非线程安全的
我们还是先来看一个LinkedHashMap的实例,操作数据的方法和HasMap是一样的,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static void main(String[] args) { 2 LinkedHashMap<String, Object> hasMap = new LinkedHashMap<String, Object>(); 3 hasMap.put("name", "zhangsan"); 4 hasMap.put("age", 20); 5 hasMap.put("addr", "北京市"); 6 hasMap.put(null, null); 7 hasMap.put("info", null); 8 hasMap.put(null, "who"); 9 10 for (Map.Entry<String, Object> entry : hasMap.entrySet()) { 11 System.out.println(entry.getKey() + "=" + entry.getValue()); 12 } 13 }
输出结果:
name=zhangsan
age=20
addr=北京市
null=who
info=null
根据输出我们可以得出以下几个结论:
LinkedHashMap的输入顺序和输出顺序是一致的。
LinkedHashMap允许Key和Value都可以null
LinkedHashMap中添加元素时,如果Key重复,则后添加的会覆盖前面已经存在的值
LinkedHashMap的具体实现
我们先来看看LinkedHashMap的定义,其中157行有这样一个定义
1 /**
2 * The head of the doubly linked list.
3 */
4 private transient Entry<K,V> header;
Entry就是LinkedHashMap基本数据结构,Entry是LinkedHashMap定义的一个内部类,继承了HaspMap.Entry,在此基础上添加了新添加了两个属性。
before、after是用于维护链表中Entry的前一个元素和后一个元素。
我们来看一下HaspMap的一个构造函数,
1 public HashMap(int initialCapacity, float loadFactor) {
2 if (initialCapacity < 0)
3 throw new IllegalArgumentException("Illegal initial capacity: " +
4 initialCapacity);
5 if (initialCapacity > MAXIMUM_CAPACITY)
6 initialCapacity = MAXIMUM_CAPACITY;
7 if (loadFactor <= 0 || Float.isNaN(loadFactor))
8 throw new IllegalArgumentException("Illegal load factor: " +
9 loadFactor);
10
11 this.loadFactor = loadFactor;
12 threshold = initialCapacity;
13 init();
14 }
此构造函数中最后有一个init的方法,但是此方法在HashMap中没有实现,LinkedHashMap中重写了该方法,用来初始化化链表。
元素的添加,修改和HashMap就一样的,虽然LinkedHashMap重写了addEntry方法,只是增加了删除eldest entry的功能。
方法removeEldestEntry始终返回false, 所以删除 eldest entry 实际上不会执行。
总结:从以上可以判断LinkedHashMap的实现就是 HashMap+LinkedList 的实现方式,用HashMap维护数据结构,用LinkList的方式维护数据插入顺序。
利用LinkedHashMap实现LRU算法缓存
转载自: http://www.cnblogs.com/xrq730/p/5052323.html
解释一下LRU:LRU即Least Recently Used,最近最少使用,也就是说,当缓存满了,会优先淘汰那些最近最不常访问的数据。
要实现这个功能,就是要记录那些元素被访问了,访问的元素应该向前排列,当然这个功能LinkedHashMap已经帮我们实现了,
注意红框的部分, recordAccess,就是将当前entry移动到链表的最前面。
前面说了,LinkedHashMap添加新的元素时会执行删除eldest entry,虽然LinkedHashMap没有实现,但是我们可以重写removeEldestEntry的方法来实现这个功能。
1 public class LRUCache extends LinkedHashMap
2 {
3 public LRUCache(int maxSize)
4 {
5 super(maxSize, 0.75F, true);
6 maxElements = maxSize;
7 }
8
9 protected boolean removeEldestEntry(java.util.Map.Entry eldest)
10 {
11 return size() > maxElements;
12 }
13
14 private static final long serialVersionUID = 1L;
15 protected int maxElements;
16 }
当元素的个数大于指定的值有,就会有原始被删除掉,也就是链表最后的元素。
转载:http://www.cnblogs.com/xrq730/p/5030920.html