深刻理解HashMap和LinkedHashMap的區別
咱們知道HashMap的變量順序是不可預測的,這意味着便利的輸出順序並不必定和HashMap的插入順序是一致的。這個特性一般會對咱們的工做形成必定的困擾。爲了實現這個功能,咱們可使用LinkedHashMap。
LinkedHashMap詳解
先看下LinkedHashMap的定義:
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
LinkedHashMap繼承自HashMap,因此HashMap的全部功能在LinkedHashMap均可以用。
LinkedHashMap和HashMap的區別就是新建立了一個Entry:
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);br/>}
}
這個Entry繼承自HashMap.Node,多了一個before,after來實現Node之間的鏈接。
經過這個新建立的Entry,就能夠保證遍歷的順序和插入的順序一致。
下面看一個LinkedHashMap插入的例子:
@Test
public void insertOrder(){
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("ddd","desk");
map.put("aaa","ask");
map.put("ccc","check");
map.keySet().forEach(System.out::println);
}
輸出結果:
ddd
aaa
ccc
能夠看到輸出結果和插入結果是一致的。
除了遍歷的順序,LinkedHashMap還有一個很是有特點的訪問順序。
咱們再看一個LinkedHashMap的構造函數:
public LinkedHashMap(int initialCapacity,
float loadFactor,
boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
前面的兩個參數initialCapacity,loadFactor咱們以前已經講過了,如今看最後一個參數accessOrder。
當accessOrder設置成爲true的時候,就開啓了 access-order。
access order的意思是,將對象安裝最老訪問到最新訪問的順序排序。咱們看個例子:br/>@Test
public void accessOrder(){
LinkedHashMap<String, String> map = new LinkedHashMap<>(16, .75f, true);
map.put("ddd","desk");
map.put("aaa","ask");
map.put("ccc","check");
map.keySet().forEach(System.out::println);
map.get("aaa");
map.keySet().forEach(System.out::println);
}
輸出結果:
ddd
aaa
ccc
ddd
ccc
aaa
咱們看到,由於訪問了一次「aaa「,從而致使遍歷的時候排到了最後。
removeEldestEntry
最後咱們看一下LinkedHashMap的一個特別的功能removeEldestEntry。這個方法是幹什麼的呢?
經過從新removeEldestEntry方法,可讓LinkedHashMap保存特定數目的Entry,一般用在LinkedHashMap用做緩存的狀況。
removeEldestEntry將會刪除最老的Entry,保留最新的。
ublic class CustLinkedHashMap<K, V> extends LinkedHashMap<K, V> {緩存
private static final int MAX_ENTRIES = 10; public CustLinkedHashMap( int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor, accessOrder); } @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > MAX_ENTRIES; }
}
看上面的一個自定義的例子,上面的例子咱們建立了一個保留10個Entry節點的LinkedHashMap。
LinkedHashMap繼承自HashMap,同時提供了兩個很是有用的功能。ide