進入高產模式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+" ");
});
}
}
複製代碼
最後運行結果以下: