WeakHashMap的简述2(源码解析)

基于jdk 1.8.0_91 的源码解析

public class WeakHashMap

extends AbstractMap

implements Map {

/**

* 默认的初始容量是16,必须是2的幂

*/

    private static final int DEFAULT_INITIAL_CAPACITY =16;

/**

* 最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换)

*/

    private static final int MAXIMUM_CAPACITY =1 <<30;

/**

* 默认加载因子

*/

    private static final float DEFAULT_LOAD_FACTOR =0.75f;

/**

* 存储数据的Entry数组,长度是2的幂。

* WeakHashMap是采用拉链法实现的,每一个Entry本质上是一个单向链表

*/

    Entry[]table;

/**

* 表示WeakHashMap的大小

*/

    private int size;

/**

* WeakHashMap的阈值,用于判断是否需要调整WeakHashMap的容量(threshold = 容量*加载因子)

*/

    private int threshold;

/**

* 加载因子实际大小

*/

    private final float loadFactor;

/**

*  queue保存的是“已被GC清除”的“弱引用的键”。

* 弱引用和ReferenceQueue 是联合使用的:如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中

*/

    private final ReferenceQueuequeue =new ReferenceQueue<>();

/**

* WeakHashMap被改变的次数

*/

    int modCount;

@SuppressWarnings("unchecked")

private Entry[] newTable(int n) {

return (Entry[])new Entry[n];

}

/**

*  定义包含“容量大小”和“加载因子”的构造函数

*/

    public WeakHashMap(int initialCapacity,float loadFactor) {

// 如果容量大小小于0 ,就抛出参数不合法异常

        if (initialCapacity <0)

throw new IllegalArgumentException("Illegal Initial Capacity: "+

initialCapacity);

// 如果容量大小>最大容量 ,就让WeakHashMap的最大容量只能是MAXIMUM_CAPACITY

        if (initialCapacity >MAXIMUM_CAPACITY)

initialCapacity =MAXIMUM_CAPACITY;

// 如果加载因子<=0  或者 加载因子没有 数字 就抛出参数不合法异常

        if (loadFactor <=0 || Float.isNaN(loadFactor))

throw new IllegalArgumentException("Illegal Load factor: "+

loadFactor);

// 找出“大于initialCapacity”的最小的2的幂

        int capacity =1;

while (capacity < initialCapacity)

//  capacity<< n 等效于 capacity 乘以 2的 N 次方

            capacity <<=1;

// 创建Entry数组,用来保存数据

        table = newTable(capacity);

// 设置“加载因子”

        this.loadFactor = loadFactor;

// 设置“WeakHashMap阈值”,当WeakHashMap中存储数据的数量达到threshold时,就需要将WeakHashMap的容量加倍。

        threshold = (int)(capacity * loadFactor);

}

/**

*  创建指定“容量大小”的构造函数

*/

    public WeakHashMap(int initialCapacity) {

this(initialCapacity,DEFAULT_LOAD_FACTOR);

}

/**

*  创建默认构造函数

*/

    public WeakHashMap() {

this(DEFAULT_INITIAL_CAPACITY,DEFAULT_LOAD_FACTOR);

}

/**

* 创建包含“子Map”的构造函数

*/

    public WeakHashMap(Map m) {

this(Math.max((int) (m.size() /DEFAULT_LOAD_FACTOR) +1,

DEFAULT_INITIAL_CAPACITY),

DEFAULT_LOAD_FACTOR);

// 将m中的全部元素逐个添加到WeakHashMap中

        putAll(m);

}

// internal utilities

/**

* 键为null的mask值。

* 因为WeakReference中允许“null的key”,若直接插入“null的key”,将其当作弱引用时,会被删除。

* 因此,这里对于“key为null”的清空,都统一替换为“key为NULL_KEY”,“NULL_KEY”是“静态的final常量”。

*/

    private static final ObjectNULL_KEY =new Object();

/**

* 对“null的key”进行特殊处理

*/

    private static Object maskNull(Object key) {

return (key ==null) ?NULL_KEY : key;

}

/**

* 还原对“null的key”的特殊处理

*/

    static Object unmaskNull(Object key) {

return (key ==NULL_KEY) ?null : key;

}

/**

*  判断“x”和“y”是否相等

*/

    private static boolean eq(Object x, Object y) {

return x == y || x.equals(y);

}

/**

* 返回索引值

* h & (length-1)保证返回值的小于length

*/

    final int hash(Object k) {

int h = k.hashCode();

// This function ensures that hashCodes that differ only by

// constant multiples at each bit position have a bounded

// number of collisions (approximately 8 at default load factor).

        h ^= (h >>>20) ^ (h >>>12);

return h ^ (h >>>7) ^ (h >>>4);

}

/**

* 返回哈希代码h 的索引

*/

    private static int indexFor(int h,int length) {

return h & (length-1);

}

/**

*  清空table中无用键值对。原理如下:

*(当WeakHashMap中某个“弱引用的key”由于没有再被引用而被GC收回时,

*  被回收的“该弱引用key”也被会被添加到"ReferenceQueue(queue)"中。

*  当我们执行expungeStaleEntries时,

*  就遍历"ReferenceQueue(queue)"中的所有key

*  然后就在“WeakReference的table”中删除与“ReferenceQueue(queue)中key”对应的键值对

*/

    private void expungeStaleEntries() {

for (Object x; (x =queue.poll()) !=null; ) {

synchronized (queue) {

@SuppressWarnings("unchecked")

Entry e = (Entry) x;

int i =indexFor(e.hash,table.length);

Entry prev =table[i];

Entry p = prev;

while (p !=null) {

Entry next = p.next;

if (p == e) {

if (prev == e)

table[i] = next;

else

                            prev.next = next;

// Must not null out e.next;

// stale entries may be in use by a HashIterator

                        e.value =null;// Help GC

                        size--;

break;

}

prev = p;

p = next;

}

}

}

}

/**

* 获取WeakHashMap的table(存放键值对的数组)

*/

    private Entry[] getTable() {

expungeStaleEntries();

return table;

}

/**

*  获取WeakHashMap的实际大小

*/

    public int size() {

if (size ==0)

return 0;

expungeStaleEntries();

return size;

}

/**

* 判断是否为空

*/

    public boolean isEmpty() {

return size() ==0;

}

/**

*  获取key对应的value

*/

    public V get(Object key) {

//进一步判断value是否为空

        Object k =maskNull(key);

int h = hash(k);

Entry[] tab = getTable();

int index =indexFor(h, tab.length);

Entry e = tab[index];

// 在“该hash值对应的链表”上查找“键值等于key”的元素

        while (e !=null) {

if (e.hash == h &&eq(k, e.get()))

return e.value;

e = e.next;

}

return null;

}

/**

* WeakHashMap是否包含key

*/

    public boolean containsKey(Object key) {

return getEntry(key) !=null;

}

/**

* 返回“键为key”的键值对

*/

    Entry getEntry(Object key) {

Object k =maskNull(key);

int h = hash(k);

Entry[] tab = getTable();

int index =indexFor(h, tab.length);

Entry e = tab[index];

while (e !=null && !(e.hash == h &&eq(k, e.get())))

e = e.next;

return e;

}

/**

*  将“key-value”添加到WeakHashMap中

*/

    public V put(K key,V value) {

Object k =maskNull(key);

int h = hash(k);

Entry[] tab = getTable();

int i =indexFor(h, tab.length);

// 若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!

        for (Entry e = tab[i]; e !=null; e = e.next) {

if (h == e.hash &&eq(k, e.get())) {

V oldValue = e.value;

if (value != oldValue)

e.value = value;

return oldValue;

}

}

// 若“该key”对应的键值对不存在于WeakHashMap中,则将“key-value”添加到table中

        modCount++;

Entry e = tab[i];

tab[i] =new Entry<>(k, value,queue, h, e);

if (++size >=threshold)

resize(tab.length *2);

return null;

}

/**

* 重新调整WeakHashMap的大小,newCapacity是调整后的单位

*/

    void resize(int newCapacity) {

Entry[] oldTable = getTable();

int oldCapacity = oldTable.length;

if (oldCapacity ==MAXIMUM_CAPACITY) {

threshold = Integer.MAX_VALUE;

return;

}

// 新建一个newTable,将“旧的table”的全部元素添加到“新的newTable”中,

// 然后,将“新的newTable”赋值给“旧的table”。

        Entry[] newTable = newTable(newCapacity);

transfer(oldTable, newTable);

table = newTable;

if (size >=threshold /2) {

threshold = (int)(newCapacity *loadFactor);

}else {

// 删除table中“已被GC回收的key对应的键值对”

            expungeStaleEntries();

transfer(newTable, oldTable);

table = oldTable;

}

}

/**

* 将WeakHashMap中的全部元素都添加到newTable中

*/

    private void transfer(Entry[] src, Entry[] dest) {

for (int j =0; j < src.length; ++j) {

Entry e = src[j];

src[j] =null;

while (e !=null) {

Entry next = e.next;

Object key = e.get();

if (key ==null) {

e.next =null;// Help GC

                    e.value =null;//  "  "

                    size--;

}else {

int i =indexFor(e.hash, dest.length);

e.next = dest[i];

dest[i] = e;

}

e = next;

}

}

}

/**

*  将"m"的全部元素都添加到WeakHashMap中

*/

    public void putAll(Map m) {

int numKeysToBeAdded = m.size();

if (numKeysToBeAdded ==0)

return;

/**

*  计算容量是否足够,

*  若“当前实际容量 < 需要的容量”,则将容量x2

*/

        if (numKeysToBeAdded >threshold) {

int targetCapacity = (int)(numKeysToBeAdded /loadFactor +1);

if (targetCapacity >MAXIMUM_CAPACITY)

targetCapacity =MAXIMUM_CAPACITY;

int newCapacity =table.length;

while (newCapacity < targetCapacity)

newCapacity <<=1;

if (newCapacity >table.length)

resize(newCapacity);

}

// 将“m”中的元素逐个添加到WeakHashMap中。

        for (Map.Entry e : m.entrySet())

put(e.getKey(), e.getValue());

}

/**

*  移除“键为key”元素

*/

    public V remove(Object key) {

Object k =maskNull(key);

int h = hash(k);

Entry[] tab = getTable();

int i =indexFor(h, tab.length);

Entry prev = tab[i];

Entry e = prev;

// 删除链表中“键为key”的元素

        while (e !=null) {

Entry next = e.next;

if (h == e.hash &&eq(k, e.get())) {

modCount++;

size--;

if (prev == e)

tab[i] = next;

else

                    prev.next = next;

return e.value;

}

prev = e;

e = next;

}

return null;

}

/**

*  移除“键值对”

* */

    boolean removeMapping(Object o) {

if (!(oinstanceof Map.Entry))

return false;

Entry[] tab = getTable();

Map.Entry entry = (Map.Entry)o;

Object k =maskNull(entry.getKey());

int h = hash(k);

int i =indexFor(h, tab.length);

Entry prev = tab[i];

Entry e = prev;

while (e !=null) {

Entry next = e.next;

if (h == e.hash && e.equals(entry)) {

modCount++;

size--;

if (prev == e)

tab[i] = next;

else

                    prev.next = next;

return true;

}

prev = e;

e = next;

}

return false;

}

/**

* 清空WeakHashMap,将所有的元素设为null

*/

    public void clear() {

while (queue.poll() !=null)

;

modCount++;

Arrays.fill(table,null);

size =0;

while (queue.poll() !=null)

;

}

/**

* 是否包含“值为value”的元素

*/

    public boolean containsValue(Object value) {

if (value==null)

return containsNullValue();

Entry[] tab = getTable();

for (int i = tab.length; i-- >0;)

for (Entry e = tab[i]; e !=null; e = e.next)

if (value.equals(e.value))

return true;

return false;

}

/**

* 判断是否包含null值

*/

    private boolean containsNullValue() {

Entry[] tab = getTable();

for (int i = tab.length; i-- >0;)

for (Entry e = tab[i]; e !=null; e = e.next)

if (e.value==null)

return true;

return false;

}

/**

* Entry是单向链表。

* 它是 “WeakHashMap链式存储法”对应的链表。

* 它实现了Map.Entry 接口,即实现getKey(), getValue(), setValue(V value), equals(Object o), hashCode()这些函数.

*/

    private static class Entryextends WeakReferenceimplements Map.Entry {

V value;

final int hash;

// 指向下一个节点

        Entrynext;

/**

* 创建下一个节点

*/

        Entry(Object key,V value,

ReferenceQueue queue,

int hash, Entry next) {

super(key, queue);

this.value = value;

this.hash  = hash;

this.next  = next;

}

@SuppressWarnings("unchecked")

public K getKey() {

return (K) WeakHashMap.unmaskNull(get());

}

public V getValue() {

return value;

}

/**

* 设置新的值

*/

        public V setValue(V newValue) {

V oldValue =value;

value = newValue;

return oldValue;

}

/**

*  判断两个Entry是否相等

*/

        public boolean equals(Object o) {

if (!(oinstanceof Map.Entry))

return false;

Map.Entry e = (Map.Entry)o;

K k1 = getKey();

Object k2 = e.getKey();

if (k1 == k2 || (k1 !=null && k1.equals(k2))) {

V v1 = getValue();

Object v2 = e.getValue();

if (v1 == v2 || (v1 !=null && v1.equals(v2)))

return true;

}

return false;

}

/**

* 实现hashCode()

*/

        public int hashCode() {

K k = getKey();

V v = getValue();

return Objects.hashCode(k) ^ Objects.hashCode(v);

}

public String toString() {

return getKey() +"=" + getValue();

}

}

/**

* HashIterator是WeakHashMap迭代器的抽象出来的父类,实现了公共了函数。

*/

    private abstract class HashIteratorimplements Iterator {

private int index;

private Entryentry;

private EntrylastReturned;

private int expectedModCount =modCount;

private ObjectnextKey;

private ObjectcurrentKey;

HashIterator() {

index = isEmpty() ?0 :table.length;

}

public boolean hasNext() {

Entry[] t =table;

while (nextKey ==null) {

Entry e =entry;

int i =index;

while (e ==null && i >0)

e = t[--i];

entry = e;

index = i;

if (e ==null) {

currentKey =null;

return false;

}

nextKey = e.get();// hold on to key in strong ref

                if (nextKey ==null)

entry =entry.next;

}

return true;

}

/**

* 获取下一个元素

*/

        protected Entry nextEntry() {

if (modCount !=expectedModCount)

throw new ConcurrentModificationException();

if (nextKey ==null && !hasNext())

throw new NoSuchElementException();

lastReturned =entry;

entry =entry.next;

currentKey =nextKey;

nextKey =null;

return lastReturned;

}

/**

* 删除当前元素

*/

        public void remove() {

if (lastReturned ==null)

throw new IllegalStateException();

if (modCount !=expectedModCount)

throw new ConcurrentModificationException();

WeakHashMap.this.remove(currentKey);

expectedModCount =modCount;

lastReturned =null;

currentKey =null;

}

}

/**

* value的迭代器

*/

    private class ValueIteratorextends HashIterator {

public V next() {

return nextEntry().value;

}

}

/**

* key的迭代器

*/

    private class KeyIteratorextends HashIterator {

public K next() {

return nextEntry().getKey();

}

}

/**

* Entry的迭代器

*/

    private class EntryIteratorextends HashIterator> {

public Map.Entry next() {

return nextEntry();

}

}

/**

* WeakHashMap的Entry对应的集合

*/

    private transient Set>entrySet;

/**

* 返回“key的集合”,实际上返回一个“KeySet对象”

*/

    public Set keySet() {

Set ks =keySet;

return (ks !=null ? ks : (keySet =new KeySet()));

}

//KeySet继承于AbstractSet,说明该集合中没有重复的Key。

    private class KeySetextends AbstractSet {

public Iterator iterator() {

return new KeyIterator();

}

public int size() {

return WeakHashMap.this.size();

}

public boolean contains(Object o) {

return containsKey(o);

}

public boolean remove(Object o) {

if (containsKey(o)) {

WeakHashMap.this.remove(o);

return true;

}

else

                return false;

}

public void clear() {

WeakHashMap.this.clear();

}

public Spliterator spliterator() {

return new KeySpliterator<>(WeakHashMap.this,0, -1,0,0);

}

}

/**

* 返回“value集合”,实际上返回的是一个Values对象

*/

    public Collection values() {

Collection vs =values;

return (vs !=null) ? vs : (values =new Values());

}

private class Valuesextends AbstractCollection {

public Iterator iterator() {

return new ValueIterator();

}

public int size() {

return WeakHashMap.this.size();

}

public boolean contains(Object o) {

return containsValue(o);

}

public void clear() {

WeakHashMap.this.clear();

}

public Spliterator spliterator() {

return new ValueSpliterator<>(WeakHashMap.this,0, -1,0,0);

}

}

/**

*  Values中的元素能够重复。因为不同的key可以指向相同的value。

*/

    public Set> entrySet() {

Set> es =entrySet;

return es !=null ? es : (entrySet =new EntrySet());

}

/**

*  EntrySet继承于AbstractSet,说明该集合中没有重复的EntrySet。

*/

    private class EntrySetextends AbstractSet> {

public Iterator> iterator() {

return new EntryIterator();

}

public boolean contains(Object o) {

if (!(oinstanceof Map.Entry))

return false;

Map.Entry e = (Map.Entry)o;

Entry candidate = getEntry(e.getKey());

return candidate !=null && candidate.equals(e);

}

public boolean remove(Object o) {

return removeMapping(o);

}

public int size() {

return WeakHashMap.this.size();

}

public void clear() {

WeakHashMap.this.clear();

}

private List> deepCopy() {

List> list =new ArrayList<>(size());

for (Map.Entry e :this)

list.add(new AbstractMap.SimpleEntry<>(e));

return list;

}

public Object[] toArray() {

return deepCopy().toArray();

}

public T[] toArray(T[] a) {

return deepCopy().toArray(a);

}

public Spliterator> spliterator() {

return new EntrySpliterator<>(WeakHashMap.this,0, -1,0,0);

}

}

/**

* 进行遍历的集合元素

*/

    @SuppressWarnings("unchecked")

@Override

    public void forEach(BiConsumer action) {

Objects.requireNonNull(action);

int expectedModCount =modCount;

Entry[] tab = getTable();

for (Entry entry : tab) {

while (entry !=null) {

Object key = entry.get();

if (key !=null) {

action.accept((K)WeakHashMap.unmaskNull(key), entry.value);

}

entry = entry.next;

if (expectedModCount !=modCount) {

throw new ConcurrentModificationException();

}

}

}

}

/**

* 替换所有元素

*/

    @SuppressWarnings("unchecked")

@Override

    public void replaceAll(BiFunction function) {

Objects.requireNonNull(function);

int expectedModCount =modCount;

Entry[] tab = getTable();;

for (Entry entry : tab) {

while (entry !=null) {

Object key = entry.get();

if (key !=null) {

entry.value = function.apply((K)WeakHashMap.unmaskNull(key), entry.value);

}

entry = entry.next;

if (expectedModCount !=modCount) {

throw new ConcurrentModificationException();

}

}

}

}

/**

* 创建一个WeakHashMapSpliterator的静态类

*/

    static class WeakHashMapSpliterator {

final WeakHashMapmap;

WeakHashMap.Entrycurrent;

int index;

int fence;

int est;

int expectedModCount;

WeakHashMapSpliterator(WeakHashMap m,int origin,

int fence,int est,

int expectedModCount) {

this.map = m;

this.index = origin;

this.fence = fence;

this.est = est;

this.expectedModCount = expectedModCount;

}

/**

* 在第一次使用时初始化围栏和大小

*/

        final int getFence() {

int hi;

if ((hi =fence) <0) {

WeakHashMap m =map;

est = m.size();

expectedModCount = m.modCount;

hi =fence = m.table.length;

}

return hi;

}

/**

* 估计集合大小

*/

        public final long estimateSize() {

getFence();

return (long)est;

}

}

/**

* KeySpliteratord 的静态类

*/

    static final class KeySpliterator

extends WeakHashMapSpliterator

implements Spliterator {

KeySpliterator(WeakHashMap m,int origin,int fence,int est,

int expectedModCount) {

super(m, origin, fence, est, expectedModCount);

}

/**

* trySplit:ArrayListSpliterator的trySplit采用二分法,将前一半数据返回,

* 如果数据太小不能分了,返回null。而ConcurrentLinkedQueue和ConcurrentLinkedDeque的相应的Spliterator处理稍微复杂一点,

* 第一次取一个,第二个取两个,不超过MAX_BATCH

* 对当前迭代器进行分割

*/

        public KeySpliterator trySplit() {

// 这里的分割方法只是把当前迭代器的开始索引和最后索引除以二而已

            int hi = getFence(), lo =index, mid = (lo + hi) >>>1;

// 需要遍历的元素个数 est 也需要除以二喇~

            return (lo >= mid) ?null :

new KeySpliterator(map, lo,index = mid,est >>>=1,

expectedModCount);

}

/**

*  在当前迭代器遍历范围遍历一遍

*/

        public void forEachRemaining(Consumer action) {

int i, hi, mc;

if (action ==null)

throw new NullPointerException();

WeakHashMap m =map;

WeakHashMap.Entry[] tab = m.table;

if ((hi =fence) <0) {

mc =expectedModCount = m.modCount;

hi =fence = tab.length;

}

else

                mc =expectedModCount;

if (tab.length >= hi && (i =index) >=0 &&

(i < (index = hi) ||current !=null)) {

WeakHashMap.Entry p =current;

current =null;// exhaust

                do {

if (p ==null)

p = tab[i++];

else {

Object x = p.get();

p = p.next;

if (x !=null) {

@SuppressWarnings("unchecked")K k =

(K) WeakHashMap.unmaskNull(x);

action.accept(k);

}

}

}while (p !=null || i < hi);

}

if (m.modCount != mc)

throw new ConcurrentModificationException();

}

/**

* 会遍历迭代器遍历的范围之内的元素,当找到第一个非空元素的时候就会停止遍历

*/

        public boolean tryAdvance(Consumer action) {

int hi;

if (action ==null)

throw new NullPointerException();

WeakHashMap.Entry[] tab =map.table;

if (tab.length >= (hi = getFence()) &&index >=0) {

while (current !=null ||index < hi) {

if (current ==null)

current = tab[index++];

else {

Object x =current.get();

current =current.next;

if (x !=null) {

@SuppressWarnings("unchecked")K k =

(K) WeakHashMap.unmaskNull(x);

action.accept(k);

if (map.modCount !=expectedModCount)

throw new ConcurrentModificationException();

return true;

}

}

}

}

return false;

}

public int characteristics() {

return Spliterator.DISTINCT;

}

}

/**

* 创建vaule迭代器

*/

    static final class ValueSpliterator

extends WeakHashMapSpliterator

implements Spliterator {

ValueSpliterator(WeakHashMap m,int origin,int fence,int est,

int expectedModCount) {

super(m, origin, fence, est, expectedModCount);

}

/**

* 对当前迭代器进行分割

*/

        public ValueSpliterator trySplit() {

int hi = getFence(), lo =index, mid = (lo + hi) >>>1;

return (lo >= mid) ?null :

new ValueSpliterator(map, lo,index = mid,est >>>=1,

expectedModCount);

}

/**

*  在当前迭代器遍历范围遍历一遍

*/

        public void forEachRemaining(Consumer action) {

int i, hi, mc;

if (action ==null)

throw new NullPointerException();

WeakHashMap m =map;

WeakHashMap.Entry[] tab = m.table;

if ((hi =fence) <0) {

mc =expectedModCount = m.modCount;

hi =fence = tab.length;

}

else

                mc =expectedModCount;

if (tab.length >= hi && (i =index) >=0 &&

(i < (index = hi) ||current !=null)) {

WeakHashMap.Entry p =current;

current =null;//排出

                do {

if (p ==null)

p = tab[i++];

else {

Object x = p.get();

V v = p.value;

p = p.next;

if (x !=null)

action.accept(v);

}

}while (p !=null || i < hi);

}

if (m.modCount != mc)

throw new ConcurrentModificationException();

}

/**

* 会遍历迭代器遍历的范围之内的元素,当找到第一个非空元素的时候就会停止遍历

*/

        public boolean tryAdvance(Consumer action) {

int hi;

if (action ==null)

throw new NullPointerException();

WeakHashMap.Entry[] tab =map.table;

if (tab.length >= (hi = getFence()) &&index >=0) {

while (current !=null ||index < hi) {

if (current ==null)

current = tab[index++];

else {

Object x =current.get();

V v =current.value;

current =current.next;

if (x !=null) {

action.accept(v);

if (map.modCount !=expectedModCount)

throw new ConcurrentModificationException();

return true;

}

}

}

}

return false;

}

public int characteristics() {

return 0;

}

}

/**

* 创建一个EntrySpliterator迭代器

*/

    static final class EntrySpliterator

extends WeakHashMapSpliterator

implements Spliterator> {

EntrySpliterator(WeakHashMap m,int origin,int fence,int est,

int expectedModCount) {

super(m, origin, fence, est, expectedModCount);

}

/**

* 对当前迭代器进行分割

*/

        public EntrySpliterator trySplit() {

int hi = getFence(), lo =index, mid = (lo + hi) >>>1;

return (lo >= mid) ?null :

new EntrySpliterator(map, lo,index = mid,est >>>=1,

expectedModCount);

}

/**

*  在当前迭代器遍历范围遍历一遍

*/

        public void forEachRemaining(Consumer> action) {

int i, hi, mc;

if (action ==null)

throw new NullPointerException();

WeakHashMap m =map;

WeakHashMap.Entry[] tab = m.table;

if ((hi =fence) <0) {

mc =expectedModCount = m.modCount;

hi =fence = tab.length;

}

else

                mc =expectedModCount;

if (tab.length >= hi && (i =index) >=0 &&

(i < (index = hi) ||current !=null)) {

WeakHashMap.Entry p =current;

current =null;// exhaust

                do {

if (p ==null)

p = tab[i++];

else {

Object x = p.get();

V v = p.value;

p = p.next;

if (x !=null) {

@SuppressWarnings("unchecked")K k =

(K) WeakHashMap.unmaskNull(x);

action.accept

(new AbstractMap.SimpleImmutableEntry(k, v));

}

}

}while (p !=null || i < hi);

}

if (m.modCount != mc)

throw new ConcurrentModificationException();

}

/**

* 会遍历迭代器遍历的范围之内的元素,当找到第一个非空元素的时候就会停止遍历

*/

        public boolean tryAdvance(Consumer> action) {

int hi;

if (action ==null)

throw new NullPointerException();

WeakHashMap.Entry[] tab =map.table;

if (tab.length >= (hi = getFence()) &&index >=0) {

while (current !=null ||index < hi) {

if (current ==null)

current = tab[index++];

else {

Object x =current.get();

V v =current.value;

current =current.next;

if (x !=null) {

@SuppressWarnings("unchecked")K k =

(K) WeakHashMap.unmaskNull(x);

action.accept

(new AbstractMap.SimpleImmutableEntry(k, v));

if (map.modCount !=expectedModCount)

throw new ConcurrentModificationException();

return true;

}

}

}

}

return false;

}

/**

* Spliterator的参数

*/

        public int characteristics() {

return Spliterator.DISTINCT;

}

}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341

推荐阅读更多精彩内容

  • 1.HashMap是一个数组+链表/红黑树的结构,数组的下标在HashMap中称为Bucket值,每个数组项对应的...
    谁在烽烟彼岸阅读 1,007评论 2 2
  • 一、基本数据类型 注释 单行注释:// 区域注释:/* */ 文档注释:/** */ 数值 对于byte类型而言...
    龙猫小爷阅读 4,251评论 0 16
  • public class HashMap extends AbstractMap implements Map, ...
    阿桃_28e7阅读 296评论 0 0
  • 转眼已2017,我将进入生命的第34年。在前30年里,按部就班的走在人生的轨道上,按照家人的意愿“稳定”前进,也一...
    与小贝的沐光飞行阅读 1,092评论 0 0
  • 一直想要学习一门技能,却不知道学啥,终于在年初选定了英语,自信满满制定了学习计划,只有小学知识储备的我,卯足了劲报...
    东涂西抹阅读 316评论 0 2