LinkedHashMap源碼剖析

前言

HashMap,比如你放了一堆key-value對進去,後面的話呢如果你要遍歷這個HashMap的話,遍歷的順序,並不是按照你插入的key-value的順序來的

LinkedHashMap,他會記錄你插入key-value的順序, 如果你在遍歷的時候,他是按照插入key-value對的順序給你遍歷出來的

LinkedHashMap是HashMap的一個子類。LinkedHashMap和TreeMap的區別,他們都可以維持key的順序,只是LinkedHashMap底層是基於鏈表來實現的,TreeMap是基於紅黑樹來實現順序的

LinkedHashMap其實原則上來說一些基本的原理和操作跟HashMap是差不多的,唯一主要的區別就是你在插入、覆蓋、刪除,他會記錄一下key-value對的順序,用一個鏈表來記錄,在遍歷的時候,就可以按照這個順序來遍歷

源碼剖析

在調用LinkedHashMap的put()方法的時候,一定會調用到HashMap的put()方法裏面去,調用完put()方法,其實就會調用afterNodeInsertion(evict);,這個方法就會去回調LinkedHahsMap裏面的子類的實現。

void afterNodeInsertion(boolean evict) { // possibly remove eldest

        LinkedHashMap.Entry<K,V> first;

        if (evict && (first = head) != null && removeEldestEntry(first)) {

            K key = first.key;

            removeNode(hash(key), key, null, false, true);

        }

}

所以說就是在這裏,回調了這個方法,這個方法裏面,他就是實現了LinkedHashMap的邏輯,來記錄插入key-value對的順序,用一個鏈表來記錄。

    Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {

        LinkedHashMap.Entry<K,V> p =

            new LinkedHashMap.Entry<K,V>(hash, key, value, e);

        linkNodeLast(p);

        return p;

    }

將節點封裝爲了一個LinkedHashMap.Entry對象,然後使用linkNodeLast(p)這個東西,將這個節點掛到一個鏈表裏去。

LinkedHashMap有一個參數的,你可以在構造的時候傳入進去,accessOrder,默認他是false,如果是默認爲false的話,那麼你比如說你get一個key,或者是覆蓋這個key的值,都不會改變他在鏈表裏的順序。

但是如果accessOrder是true的話,那麼如果你get一個key,或者是覆蓋這個key的值,就會導致個key-value對順序會在鏈表裏改變,他會被挪動到鏈表的尾部去

你刪除某個元素的時候,就會將那個元素從鏈表裏給摘除

在迭代的時候,LinkedHashMap裏面會從鏈表的頭部開始迭代,這樣通過這個鏈表就可以維持他的一個順序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章