LinkedHashMap 保持有序迭代原理

以前一直有這個疑問,今天有時間就把源碼看了看終於知道了原理。分享給你們也作筆記本身能夠隨後查看。
java

linkedHashMap entry 繼承了hashMap.Entry 而後定義了一個before與after用來存儲當前key的上一個值引用和下一個值的引用。而後再addBefore的時候,把上一個值設置成當前對象引用。由於如今還不知道下一個是什麼,因此默認也是當前對象引用。this

  */
    private static class Entry<K,V> extends HashMap.Entry<K,V> {
        // These fields comprise the doubly linked list used for iteration.
        Entry<K,V> before, after;

        Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
            super(hash, key, value, next);
        }


        /**
         * Inserts this entry before the specified existing entry in the list.
         */
        private void addBefore(Entry<K,V> existingEntry) {
            after  = existingEntry;
            before = existingEntry.before;
            before.after = this;
            after.before = this;
        }

而後linkedHashMap 定義了一個header變量用來存儲第一個值的引用地址,這樣迭代的時候就先迭代header,而後根據header 的next找到下一個迭代對象。code

private transient Entry<K,V> header;

而後經過LinkedHashMapIterator的nextEntry方法就能看出nextEntry = e.after。 也就是說nextEntry是上一個值的下一個值。上一個值是當前對象,下一個值也就等於下一個對象,因此這就是它保持有序的原理。對象

private abstract class LinkedHashIterator<T> implements Iterator<T> {
        Entry<K,V> nextEntry    = header.after;
        Entry<K,V> lastReturned = null;

        /**
         * The modCount value that the iterator believes that the backing
         * List should have.  If this expectation is violated, the iterator
         * has detected concurrent modification.
         */
        int expectedModCount = modCount;

        public boolean hasNext() {
            return nextEntry != header;
        }

        public void remove() {
            if (lastReturned == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();

            LinkedHashMap.this.remove(lastReturned.key);
            lastReturned = null;
            expectedModCount = modCount;
        }

        Entry<K,V> nextEntry() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (nextEntry == header)
                throw new NoSuchElementException();

            Entry<K,V> e = lastReturned = nextEntry;
            nextEntry = e.after;
            return e;
        }
    }


簡單來講,就是第一個賦值是給header,第二次賦值是給header.after。繼承

而後每次迭代就經過after知道了下一個值,也就保持了有序。ci

相關文章
相關標籤/搜索