AAC学习笔记——SafeIterableMap

SafeIterableMap是链表实现的,是个模拟的Map,它不是线程安全的。它在androidx.arch.core.internal包,看的出来谷歌并不建议直接使用它。
这个类提供了迭代器,支持升序、降序以及附加方式生成。在迭代器使用时,之前的迭代器即失效,并且迭代器存在的期间支持删除操作。


Entry

从SafeIterableMap开始看起:

public class SafeIterableMap<K, V> implements Iterable<Map.Entry<K, V>> {
    //开始的入口
    Entry<K, V> mStart;
    private Entry<K, V> mEnd;
    // 在List<WeakReference>上使用WeakHashMap,这样我们就不必手动删除其中含有null的WeakReferences。
    private WeakHashMap<SupportRemove<K, V>, Boolean> mIterators = new WeakHashMap<>();
    private int mSize = 0;

从开始的定义发现,首先需要要看一下Entry。

这里说一下Map.Entry。他是MAP里面的一个条目(键值对),可以通过Map.entrySet方法返回它。想要获得对条目的引用,必须使用它的迭代器获得。这个对象仅在迭代期间有效,确切地说,如果在迭代器返回后是无法修改条目的,必须使用setValue操作。

有的说法是使用它可以返回完整的键值对,但我觉得这种说法并不全面。

    static class Entry<K, V> implements Map.Entry<K, V> {
        final K mKey;
        final V mValue;
        Entry<K, V> mNext;
        Entry<K, V> mPrevious;
        //构造器
        Entry(@NonNull K key, @NonNull V value) {mKey = key; this.mValue = value;}
   
        public K getKey() {return mKey;}
        public V getValue() {return mValue;}

        //如果想修改它,会直接抛异常
        @Override
        public V setValue(V value) {throw new UnsupportedOperationException("An entry modification is not supported");}

        @Override
        public String toString() {return mKey + "=" + mValue;}

        @SuppressWarnings("ReferenceEquality")
        @Override
        public boolean equals(Object obj) {...}

        //每个 Java 对象都有 hashCode() 方法,都可通过该方法获得它的 hashCode 值。得到这个对象的 hashCode 值之后,系统会根据该 hashCode 值来决定该元素的存储位置。
        @Override
        public int hashCode() {return mKey.hashCode() ^ mValue.hashCode();}
    }

通过上面两段代码,总结来说Entry就是每个独立的元素。

get、put、putIfAbsent

   //链表get的标准写法
   protected Entry<K, V> get(K k) {
        Entry<K, V> currentNode = mStart;
        while (currentNode != null) {
            if (currentNode.mKey.equals(k)) {
                break;
            }
            currentNode = currentNode.mNext;
        }
        return currentNode;
    }

    public V putIfAbsent(@NonNull K key, @NonNull V v) {
        Entry<K, V> entry = get(key); //找
        if (entry != null) {          //找到就返回
            return entry.mValue;
        }
        put(key, v);                  //找不到就增加
        return null;
    }

    protected Entry<K, V> put(@NonNull K key, @NonNull V v) {
        Entry<K, V> newEntry = new Entry<>(key, v);
        mSize++;
        if (mEnd == null) {           //如果本来就是空的直接增加
            mStart = newEntry;        //SafeIterableMap.mStart
            mEnd = mStart;            //SafeIterableMap.mEnd,指针指向mStart
            return newEntry;
        }

        mEnd.mNext = newEntry;       //指向后一节点
        newEntry.mPrevious = mEnd;   //指向前一节点
        mEnd = newEntry;             //SafeIterableMap.mEnd,指针指向newEntry
        return newEntry;             //返回put的Entry

    }

第一个永远是mStart,最新的永远是mEnd。

主角Iterator

    private abstract static class ListIterator<K, V> implements Iterator<Map.Entry<K, V>>,
            SupportRemove<K, V> {
        Entry<K, V> mExpectedEnd;   //预计结束的节点
        Entry<K, V> mNext;          //开始节点

        ListIterator(Entry<K, V> start, Entry<K, V> expectedEnd) {
            this.mExpectedEnd = expectedEnd;
            this.mNext = start;
        }

        @Override
        public boolean hasNext() {
            return mNext != null;
        }

        @SuppressWarnings("ReferenceEquality")
        @Override
        public void supportRemove(@NonNull Entry<K, V> entry) {
            if (mExpectedEnd == entry && entry == mNext) {
                mNext = null;
                mExpectedEnd = null;
            }

            if (mExpectedEnd == entry) {
                mExpectedEnd = backward(mExpectedEnd);  //传入的Eentry等于预计结束,则向后移动一个节点
            }

            if (mNext == entry) {                       //传入的Eentry等于开始,则向前移动一个节点
                mNext = nextNode();
            }
        }

        @SuppressWarnings("ReferenceEquality")
        private Entry<K, V> nextNode() {
            if (mNext == mExpectedEnd || mExpectedEnd == null) {
                return null;
            }
            return forward(mNext);
        }

        @Override
        public Map.Entry<K, V> next() {
            Map.Entry<K, V> result = mNext;
            mNext = nextNode();
            return result;
        }

        abstract Entry<K, V> forward(Entry<K, V> entry);

        abstract Entry<K, V> backward(Entry<K, V> entry);
    }

    static class AscendingIterator<K, V> extends ListIterator<K, V> {
        AscendingIterator(Entry<K, V> start, Entry<K, V> expectedEnd) {
            super(start, expectedEnd);
        }

        @Override
        Entry<K, V> forward(Entry<K, V> entry) {
            return entry.mNext;                     //向后移动指针
        }

        @Override
        Entry<K, V> backward(Entry<K, V> entry) {
            return entry.mPrevious;               //向前移动指针
        }
    }

    private static class DescendingIterator<K, V> extends ListIterator<K, V> {

        DescendingIterator(Entry<K, V> start, Entry<K, V> expectedEnd) {
            super(start, expectedEnd);
        }

        @Override
        Entry<K, V> forward(Entry<K, V> entry) {
            return entry.mPrevious;             //向前移动指针
        }

        @Override
        Entry<K, V> backward(Entry<K, V> entry) {
            return entry.mNext;                 //向后移动指针
        }
    }
    private class IteratorWithAdditions implements Iterator<Map.Entry<K, V>>, SupportRemove<K, V> {
        private Entry<K, V> mCurrent;
        private boolean mBeforeStart = true;

        IteratorWithAdditions() {
        }

        @SuppressWarnings("ReferenceEquality")
        @Override
        public void supportRemove(@NonNull Entry<K, V> entry) {
            if (entry == mCurrent) {
                mCurrent = mCurrent.mPrevious;
                mBeforeStart = mCurrent == null;
            }
        }

        @Override
        public boolean hasNext() {
            if (mBeforeStart) {
                return mStart != null;
            }
            return mCurrent != null && mCurrent.mNext != null;
        }

        @Override
        public Map.Entry<K, V> next() {
            if (mBeforeStart) {
                mBeforeStart = false;
                mCurrent = mStart;
            } else {
                mCurrent = mCurrent != null ? mCurrent.mNext : null;
            }
            return mCurrent;
        }
    }
   

上面是管理迭代器列表、前移、后移以及附加的几个内部类。在迭代器的使用:


 
    //升序迭代器,它不包括迭代期间添加的新元素
    public Iterator<Map.Entry<K, V>> iterator() {
        ListIterator<K, V> iterator = new AscendingIterator<>(mStart, mEnd);
        mIterators.put(iterator, false);
        return iterator;
    }

    //降序迭代器,它不包括迭代期间添加的新元素     
    public Iterator<Map.Entry<K, V>> descendingIterator() {
        DescendingIterator<K, V> iterator = new DescendingIterator<>(mEnd, mStart);
        mIterators.put(iterator, false);
        return iterator;
    }

    //返回一个附加的迭代器。     
    public IteratorWithAdditions iteratorWithAdditions() {
        @SuppressWarnings("unchecked")
        IteratorWithAdditions iterator = new IteratorWithAdditions();
        mIterators.put(iterator, false);
        return iterator;
    }
    
    public V remove(@NonNull K key) {
        Entry<K, V> toRemove = get(key);
        if (toRemove == null) {
            return null;
        }
        mSize--;
        if (!mIterators.isEmpty()) {
            for (SupportRemove<K, V> iter : mIterators.keySet()) {
                iter.supportRemove(toRemove);
            }
        }

        if (toRemove.mPrevious != null) {
            toRemove.mPrevious.mNext = toRemove.mNext;
        } else {
            mStart = toRemove.mNext;
        }

        if (toRemove.mNext != null) {
            toRemove.mNext.mPrevious = toRemove.mPrevious;
        } else {
            mEnd = toRemove.mPrevious;
        }

        toRemove.mNext = null;
        toRemove.mPrevious = null;
        return toRemove.mValue;
    }

核心remove

    public V remove(@NonNull K key) {
        Entry<K, V> toRemove = get(key);  //定位到要删除的节点
        if (toRemove == null) { return null;}
        mSize--;
        if (!mIterators.isEmpty()) {      //存在mIterators,就遍历并且逐一调整每个节点位置
            for (SupportRemove<K, V> iter : mIterators.keySet()) {
                iter.supportRemove(toRemove);  
            }
        }

        if (toRemove.mPrevious != null) {
            toRemove.mPrevious.mNext = toRemove.mNext;
        } else {
            mStart = toRemove.mNext;
        }

        if (toRemove.mNext != null) {
            toRemove.mNext.mPrevious = toRemove.mPrevious;
        } else {
            mEnd = toRemove.mPrevious;
        }

        toRemove.mNext = null;
        toRemove.mPrevious = null;
        return toRemove.mValue;
    }

猜你喜欢

转载自blog.csdn.net/jouter/article/details/83549931