进入高产模式java
Map接口的哈希表与链表实现,这个跟HashMap不同的地方有这么一个,就是有可预测的顺序,咱们会在下面说到。这个实现不一样于HashMap的地方是它内部维护了一个关联全部键值对的双相链表,这个链表定义了迭代的顺序是按照插入时的顺序仍是访问时的顺序。算法
LinkedHashMap提供了一个构造函数,能使原有的Map转变为LinkedHashMap,而且这个LinkedHashMap中元素的顺序与源中元素顺序相同。缓存
LinkedHashMap提供了一个构造函数LinkedHashMap(int,float,boolean) ,咱们能经过这个构造函数指定排序顺序。当为ture时,LinkedHashMap会将按照访问的顺序进行排序。安全
removeEldestEntry这个方法即是LinkedHashMap判断是否删除元素的依据,当为true时,删除第一个元素。若是要使用通常须要重写。ide
这个类提供全部map的可选操做,而且容许null元素。想HashMap同样,对基本操做如add、contains、remove他提供恒定时间的性能表现。而且性能比HashMap只低一点点,由于要维护一个双向链表。对全部元素进行迭代,在LinkedHashMap中这个所须要的时间与其size成正比。可是HashMap花费更多,须要与其容量成正比的时间。函数
有两个参数影响其性能,initial capacity与load factor 他们的定义与在HashMap中的彻底相同。性能
这个实现不是同步的,若是有多个线程访问,而且至少有一个线程对其进行告终构修改,必需要进行额外的操做保证其线程安全性,好比使用Map m = Collections.synchronizedMap(new LinkedHashMap(...));this
这里的结构改变与其余的集合类有些不一样,在这个LinkedHashMap是以访问顺序进行排序时,get也算结构改变。spa
这个类返回的全部迭代器Iterator都是基于快速失败机制fail-fast的。线程
这个类返回的分裂迭代器Spliterator是后期绑定以及快速失败的,而且被标记为ORDERED。
LinkedHashMap继承于HashMap,因此LinkedHashMap除了双向链表外,其余的都与HashMap大同小异。在这一篇,咱们将关注点放到LinkedHashMap的实际使用上,因此存储结构咱们用图来解释。
咱们如今利用LinkedHashMap来作一个简单的LRU。
import java.util.LinkedHashMap;
import java.util.Map;
/** * @author lichaobao * @date 2019/5/30 * @QQ 1527563274 */
public class LRULinkedHashMap<K,V> extends LinkedHashMap<K,V> {
private int capacity;
public LRULinkedHashMap(int capacity){
super(4,0.75f,true);
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
boolean ifRemove = size() > capacity;
if(ifRemove){
System.out.println("内存不够即将删除:"+eldest.getKey()+"="+eldest.getValue());
}
return ifRemove;
}
public static void main(String[] args){
Map<Integer,String> map = new LRULinkedHashMap<Integer, String>(4);
map.put(1,"one");
map.put(2,"two");
map.put(3,"three");
map.put(4,"four");
System.out.println("==========访问前数据顺序==============");
map.forEach((key,value)->{
System.out.print(key+"="+value+" ");
});
System.out.println("\n============如今开始get(1)=============");
System.out.println(map.get(1));
System.out.println("==========访问1后数据顺序==============");
map.forEach((key,value)->{
System.out.print(key+"="+value+" ");
});
System.out.println("\n==============如今开始增长第五个数据 put(5,\"five\")==========");
map.put(5,"five");
System.out.println("================最后map中的元素以及顺序为================");
map.forEach((key,value)->{
System.out.print(key+"="+value+" ");
});
}
}
复制代码
最后运行结果以下: