Java學習之LinkedHashMap學習總結


前言:

     在學習LRU算法的時候,看到LruCache源碼實現是基於LinkedHashMap,今天學習一下LinkedHashMap的好處以及如何實現lru緩存機制的。

需求背景:

     LRU這個算法就是把最近一次使用時間離現在時間最遠的數據刪除掉,而實現LruCache將會頻繁的執行插入、刪除等操作,我們就會想到使用LinkedList,但是我們又要基於Key-Value來保存數據,這個時候我們就會想起HashMap,但是HashMap不能像linkedList那樣保留數據的插入順序,如果要使用HashMap的話可以使用它的一個子類LinkedHashMap。

LinkedHashMap介紹:

     LinkedHashMap是Map接口哈希表和鏈接列表實現,具有可預知的迭代順序。此實現提供所有可選的映射操作,並允許使用null值和null鍵。此類不保證映射的順序,特別是它不保證該順序恆久不變, LinkedHashMap實現與HashMap的不同之處在於,后者維護着一個運行於所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,該迭代順序可以是插入順序或者是訪問順序。根據鏈表中元素的順序可以分為:按插入順序的鏈表,和按訪問順序(調用get方法)的鏈表。默認是按插入順序排序,如果指定按訪問順序排序,那么調用get方法后,會將這次訪問的元素移至鏈表尾部,不斷訪問可以形成按訪問順序排序的鏈表。 可以重寫removeEldestEntry方法返回true值指定插入元素時移除最老的元素。更多關於LinkedHashMap的知識介紹請查看這篇博客,博客地址:http://www.cnblogs.com/children/archive/2012/10/02/2710624.html

LinkedHashMap使用:

因為我們這里為了實現LRU算法,排序方式 設置為true 訪問順序排序

        int initialCapacity = 10;//初始化容量
        float loadFactor = 0.75f;//加載因子,一般是 0.75f
        boolean accessOrder = true;//排序方式 false 基於插入順序  true  基於訪問順序
        Map<String, Integer> map = new LinkedHashMap<>(initialCapacity, loadFactor, accessOrder);

具體看下效果:

   for (int i = 0; i < 10; i++) {
            map.put(String.valueOf(i), i);
        }
        //訪問前順序
        for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, Integer> next = it.next();
            Log.e(TAG, "linkedMap--before-->" + next.getKey());
        }

        //模擬訪問
        map.get("5");

        //訪問后數據
        for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, Integer> next = it.next();
            Log.e(TAG, "linkedMap--after-->" + next.getKey());
        }
    }

運行結果發現訪問過的5未知發生了變化 說明是基於訪問排序的。我們接下來再看下如何移除過期的。

       final int initialCapacity = 10;//初始化容量
        float loadFactor = 0.75f;//加載因子,一般是 0.75f
        boolean accessOrder = true;//排序方式 false 基於插入順序  true  基於訪問順序
        //Map<String, Integer> map = new LinkedHashMap<>(initialCapacity, loadFactor, accessOrder);
        Map<String, Integer> map = new LinkedHashMap(initialCapacity, loadFactor, accessOrder) {

            @Override
            protected boolean removeEldestEntry(Entry eldest) {
                return size() > initialCapacity;
            }
        };
        for (int i = 0; i < 15; i++) {
            map.put(String.valueOf(i), i);
        }
        //訪問前順序
        for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, Integer> next = it.next();
            Log.e(TAG, "linkedMap--before-->" + next.getKey());
        }

我們容量定的10個,我們插入15個 我們發現最先插入的五個不見了,說明LRU算法起到效果了。


免責聲明!

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



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