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;
}