深入理解HashMap和LinkedHashMap的區別


深入理解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);

        }

    }

這個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的意思是,將對象安裝最老訪問到最新訪問的順序排序。我們看個例子:

@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,同時提供了兩個非常有用的功能。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM