WeakhashMap源码2
public class WeakHashMapIteratorTest {
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
Map map = new WeakHashMap1(7);
for (int i = 0; i < 3; i++) {
map.put("k" + i, "v" + i);
}
// 通过entrySet()遍历WeakHashMap的key-value
iteratorHashMapByEntryset(map);
// 通过keySet()遍历WeakHashMap的key-value
iteratorHashMapByKeyset(map);
// 单单遍历WeakHashMap的value
iteratorHashMapJustValues(map);
} // 通过entry set遍历WeakHashMap
@SuppressWarnings("rawtypes")
private static void iteratorHashMapByEntryset(Map map) {
if (map == null)
return;
String key = null;
String integ = null;
// entrySet()返回new EntrySet()这个对象。iterator()返回new EntryIterator()对象。
Collection c = map.entrySet();//c = [k2=v2, k1=v1, k0=v0] ,有值了。c是EntrySet类型。
Iterator iter = c.iterator();//遍历时候还是调用HashIterator的next和hasNext方法,不是调用Collection c的方法。
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
key = (String) entry.getKey();
integ = (String) entry.getValue();
}
System.out.println("iteratorHashMapByEntryset--->>>size: " + map.size());
} /*
* 通过keyset来遍历WeakHashMap
*/
private static void iteratorHashMapByKeyset(Map map) {
if (map == null)
return;
String key = null;
String integ = null;
Collection c = map.keySet();//[k2, k1, k0]。c是KeySet类型。
Iterator iter = c.iterator();//遍历时候还是调用HashIterator的next和hasNext方法,不是调用Collection c的方法。
while (iter.hasNext()) {
key = (String) iter.next();
integ = (String) map.get(key);
}
System.out.println("iteratorHashMapByKeyset--->>>size: " + map.size());
} /*
* 遍历WeakHashMap的values
*/
private static void iteratorHashMapJustValues(Map map) {
if (map == null)
return;
String key = null;
String integ = null;
Collection c = map.values();//c是Values类型。
Iterator iter = c.iterator();//遍历时候还是调用HashIterator的next和hasNext方法,不是调用Collection c的方法。
System.out.println("iteratorHashMapJustValues--->>>size: " + map.size());
while (iter.hasNext()) {
key = (String) iter.next();
integ = (String) map.get(key);
}
}
}
public class WeakHashMap1<K,V> extends AbstractMap1<K,V> implements Map<K,V> {//弱hashmap
private static final int DEFAULT_INITIAL_CAPACITY = 16;//初始容量2的幂次方
private static final int MAXIMUM_CAPACITY = 1 << 30;//最大容量2^30
private static final float DEFAULT_LOAD_FACTOR = 0.75f;//加载因子
Entry<K,V>[] table;//实际元素位置,桶
private int size;//大小
private int threshold;//阈值:threshold = 容量*加载因子
private final float loadFactor;//加载因素
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();//Enter的key被回收,Entry进入queue队列。弱键失效的时候会把Entry添加到这个队列中。
int modCount;// WeakHashMap被改变的次数。新增、删除、clear会加一。 @SuppressWarnings("unchecked")
private Entry<K,V>[] newTable(int n) {//Entry数组,Entry是一个弱引用,
return (Entry<K,V>[]) new Entry<?,?>[n];
} public WeakHashMap1(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Initial Capacity: "+ initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;// 最大容量只能是MAXIMUM_CAPACITY
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal Load factor: "+ loadFactor);
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;//capacity是2的幂次方,一直乘以2去接近大小。 找出“大于initialCapacity”的最小的2的幂
table = newTable(capacity);
this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor);//超过12就扩容
} public WeakHashMap1(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public WeakHashMap1() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
public WeakHashMap1(Map<? extends K, ? extends V> m) {
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY),
DEFAULT_LOAD_FACTOR);
putAll(m);
}
//若直接插入“null的key”,将其当作弱引用时,会被删除。这里对于“key为null”的清空,都统一替换为“key为NULL_KEY”,“NULL_KEY”是“静态的final常量”。
private static final Object NULL_KEY = new Object();
//key是null返回空的Object
private static Object maskNull(Object key) {
return (key == null) ? NULL_KEY : key;
}
//key是空Object返回null
static Object unmaskNull(Object key) {
return (key == NULL_KEY) ? null : key;
}
//地址相等
private static boolean eq(Object x, Object y) {
return x == y || x.equals(y);
}
final int hash(Object k) {
int h = k.hashCode();//native方法
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
private static int indexFor(int h, int length) {//就是对长度取模。
return h & (length-1);//16-1=15。8,4,2,1组合<=15,所以是对16去模。
} //删除过期的
private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null; ) {
synchronized (queue) {
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) x;//queue里面排队的是整个Entry,不是key哦。
int i = indexFor(e.hash, table.length);//对长度取模,不需要探测。链式。 //需要3个指针,prev,p,next.
Entry<K,V> prev = table[i];
Entry<K,V> p = prev;
while (p != null) {//null就找到最后去了。
Entry<K,V> next = p.next;
if (p == e) {//
if (prev == e)//第一个节点
table[i] = next;//置换table[i]。e就没有用了。
else
prev.next = next;//移除e节点。e就没有用了。
e.value = null; // 帮助 value GC,不帮助key来gc。value为null会加入queue中。e为什么不置为null?已经断开引用了。
size--;
break;
}
prev = p;
p = next;
}
}
}
} private Entry<K,V>[] getTable() {
expungeStaleEntries();//gettable时候。会先删除过期的元素,再返回table。
return table;
}
public int size() {//size也会回收脏数据
if (size == 0)
return 0;
expungeStaleEntries();
return size;
}
public boolean isEmpty() {
return size() == 0;
} public V get(Object key) {//get时候会回收脏数据
Object k = maskNull(key);
int h = hash(k);
Entry<K,V>[] tab = getTable();
int index = indexFor(h, tab.length);
Entry<K,V> e = tab[index];
while (e != null) {// 在“该hash值对应的链表”上查找“键值等于key”的元素
if (e.hash == h && eq(k, e.get()))//hash相等,并且key相等。
return e.value;
e = e.next;
}
return null;
}
public boolean containsKey(Object key) {
return getEntry(key) != null;
}
public Entry<K,V> getEntry(Object key) {
Object k = maskNull(key);
int h = hash(k);
Entry<K,V>[] tab = getTable();
int index = indexFor(h, tab.length);
Entry<K,V> e = tab[index];
while (e != null && !(e.hash == h && eq(k, e.get())))
e = e.next;
return e;
}
public V put(K key, V value) {//put也会回收脏数据
Object k = maskNull(key);//key=null时候,key变为NULL_KEY = new Object()是一个static final内存,不会加到queue去回收?
int h = hash(k);
Entry<K,V>[] tab = getTable();
int i = indexFor(h, tab.length);
for (Entry<K,V> e = tab[i]; e != null; e = e.next) {
if (h == e.hash && eq(k, e.get())) {//覆盖之前的value
V oldValue = e.value;
if (value != oldValue)
e.value = value;
return oldValue;
}
}
modCount++;
Entry<K,V> e = tab[i];
tab[i] = new Entry<>(k, value, queue, h, e);//添加新元素
if (++size >= threshold)//size大于3/4=12就扩容2倍32,
resize(tab.length * 2);//添加的时候,大于阈值,扩容2倍。已经是最大容量,就不扩容,继续放,链表无限容量。
return null;
} void resize(int newCapacity) {//扩容也会回收脏数据
Entry<K,V>[] oldTable = getTable();
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {//已经是最大容量,就不扩容,设置阈值返回。还可以继续放,无限容量,因为是链表。
threshold = Integer.MAX_VALUE;
return;
}
Entry<K,V>[] newTable = newTable(newCapacity);//新的Entry数组,
transfer(oldTable, newTable);//旧的map移到新的map
table = newTable;
//扩容时候会消除脏数据,大于3/8=6就设置阈值为新的24,扩容完毕。
if (size >= threshold / 2) {
threshold = (int)(newCapacity * loadFactor);
//消除脏数据之后小于3/8=6,就不扩容。
} else {//transfer中已经将原始数组置为null了,脏数据没有拷贝过去。
expungeStaleEntries();
transfer(newTable, oldTable);//因为在transfer的时候会清除失效的Entry,所以元素个数可能没有那么大了,就不需要扩容了
table = oldTable;
}
} //旧数组移到新数组,不拷贝脏数据。
private void transfer(Entry<K,V>[] src, Entry<K,V>[] dest) {
for (int j = 0; j < src.length; ++j) {
Entry<K,V> e = src[j];//e最开始是数组第一个元素。
src[j] = null;
while (e != null) {
Entry<K,V> next = e.next;
Object key = e.get();
if (key == null) {//脏数据
//断掉后面的引用,前面的引用已经被断掉了。
e.next = null; // Help GC,key和queue为什么不置为null?或者直接e置为null?e已经没人使用了。
e.value = null; // " "
size--;
} else {
int i = indexFor(e.hash, dest.length);
e.next = dest[i];//断掉了后面的引用,如果后面是脏数据,就没有人引用脏数据了。
dest[i] = e;
}
e = next;
}
}
} public void putAll(Map<? extends K, ? extends V> m) {
int numKeysToBeAdded = m.size();
if (numKeysToBeAdded == 0)
return;
if (numKeysToBeAdded > threshold) {//大于阈值扩容
int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);//不是2倍。targetCapacity是目标大小根据numKeysToBeAdded计算
if (targetCapacity > MAXIMUM_CAPACITY)
targetCapacity = MAXIMUM_CAPACITY;//扩容后的大小,最大不能超过
int newCapacity = table.length;//newCapacity是初始现在大小比如16,原始大小。
while (newCapacity < targetCapacity)
newCapacity <<= 1;//原始大小一直乘以2接近扩容后大小。大于targetCapacity的最小值。
if (newCapacity > table.length)
resize(newCapacity);//扩容
}
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
put(e.getKey(), e.getValue());
} public V remove(Object key) {
Object k = maskNull(key);
int h = hash(k);
Entry<K,V>[] tab = getTable();
int i = indexFor(h, tab.length);
Entry<K,V> prev = tab[i];
Entry<K,V> e = prev;
//3个指针
while (e != null) {
Entry<K,V> 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 (!(o instanceof Map.Entry))
return false;
Entry<K,V>[] tab = getTable();
Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
Object k = maskNull(entry.getKey());
int h = hash(k);
int i = indexFor(h, tab.length);
Entry<K,V> prev = tab[i];
Entry<K,V> e = prev;
//3个指针
while (e != null) {
Entry<K,V> 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;
} public void clear() {// 清空WeakHashMap,将所有的元素设为null
// 一直出队,出完为止
while (queue.poll() != null) ;
modCount++;
Arrays.fill(table, null);//table全是null
size = 0;
while (queue.poll() != null) ;
} public boolean containsValue(Object value) {
if (value==null)
return containsNullValue(); Entry<K,V>[] tab = getTable();
for (int i = tab.length; i-- > 0;)
for (Entry<K,V> e = tab[i]; e != null; e = e.next)
if (value.equals(e.value))
return true;
return false;
} private boolean containsNullValue() {
Entry<K,V>[] tab = getTable();
for (int i = tab.length; i-- > 0;)
for (Entry<K,V> e = tab[i]; e != null; e = e.next)
if (e.value==null)
return true;
return false;
} @SuppressWarnings("unchecked")
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
int expectedModCount = modCount; Entry<K, V>[] tab = getTable();
for (Entry<K, V> entry : tab) {
while (entry != null) {
Object key = entry.get();
if (key != null) {
action.accept((K)WeakHashMap1.unmaskNull(key), entry.value);
}
entry = entry.next; if (expectedModCount != modCount) {
throw new ConcurrentModificationException();
}
}
}
} @SuppressWarnings("unchecked")
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);
int expectedModCount = modCount; Entry<K, V>[] tab = getTable();;
for (Entry<K, V> entry : tab) {
while (entry != null) {
Object key = entry.get();
if (key != null) {
entry.value = function.apply((K)WeakHashMap1.unmaskNull(key), entry.value);
}
entry = entry.next; if (expectedModCount != modCount) {
throw new ConcurrentModificationException();
}
}
}
} private transient Set<Map.Entry<K,V>> entrySet;// WeakHashMap的Entry对应的集合 //返回key集合value集合entry集合的方法。
public Set<K> keySet() {//Map的key集合转换成Set
// Set<K> ks1 = super.keySet();//[k2, k1, k0],也是所有数据都出来了。
Set<K> ks = keySet;
if (ks == null) {
ks = new KeySet();//new KeySet()时候就把key全部赋值给ks了。
keySet = ks;
}
return ks;
}
//value的集合,map改变这个values也改变。collection删除时候map也会删除。 不支持添加方法。
public Collection<V> values() {
// Collection<V> vals = super.values();//[v2, v1, v0],也是所有数据都出来了。
Collection<V> vs = values;
if (vs == null) {
vs = new Values();//new Values()时候就把v全部赋值给vs了。
values = vs;
}
return vs;
}
//map改变set也跟着改变。
public Set<Map.Entry<K,V>> entrySet() {//Map的所有集合转成Set
Set<Map.Entry<K,V>> es = entrySet;//这里没值,new EntrySet()之后就有值了就是map所有的元素。
return es != null ? es : (entrySet = new EntrySet());
}
//-----------------------------------实体Entry---------------------------------------------------------
//Entry的key只有Entry引用,gc时候内存不足,key的内存就回收,key置为null。清理时候,这个脏Entry就会断开引用等待gc。
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {// 它实现了Map.Entry 接口,
V value;
final int hash;
Entry<K,V> next; Entry(Object key, V value, ReferenceQueue<Object> queue, int hash, Entry<K,V> next) {
super(key, queue);//key变成了弱引用。queue是当key仅仅弱引用指向时候,把Entry这个WeakReference加入到的队列。
this.value = value;
this.hash = hash;
this.next = next;//只有key的内存是弱引用指向,gc时候是不会考虑弱引用的,所以key会被gc,value和queue不是弱引用。
} @SuppressWarnings("unchecked")
public K getKey() {
return (K) WeakHashMap1.unmaskNull(get());//get()返回key
} public V getValue() {
return value;
} public V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
} public boolean equals(Object o) {//key相等==或者equals相等,并且value相等==或者equals相等,就相等。
if (!(o instanceof 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;
} public int hashCode() {
K k = getKey();
V v = getValue();
//hashcode是通过对象key或者value的native方法来获取hashcode。Map的hashcode是key的hash值和value的hash值进行异或。
return Objects.hashCode(k) ^ Objects.hashCode(v);
} public String toString() {
return getKey() + "=" + getValue();
}
}
//-------------------------------3个集合和3个遍历器-------------------------------------------------
private abstract class HashIterator<T> implements Iterator<T> {//for循环Iterator接口实例时候,会调用hasNext和next方法。必须重写hasNext和next方法,其余2个方法不是抽象方法不用重写。
private int index;//一开始总大小,不是实际大小。下一次遍历时的数组的位置。
private Entry<K,V> entry;//开始为null。下一次遍历时的链表的位置。
private Entry<K,V> lastReturned;//开始为null。遍历时当前返回的元素。
private int expectedModCount = modCount;
private Object nextKey;//下一次遍历时的元素的key。
private Object currentKey;//遍历时当前返回的元素的key。 HashIterator() {
index = isEmpty() ? 0 : table.length;//内部类直接使用外部类方法,
} //数组元素的位置index,链表中的位置entry。nextKey、entry、
public boolean hasNext() {
Entry<K,V>[] t = table; while (nextKey == null) {//第一次进来为null,nextKey!=null就说明有下一个。
Entry<K,V> e = entry;//第一次进来为null
int i = index;
while (e == null && i > 0)//第一次进来或者到了链表的末尾,就为null。就要查找数组的下一个。
e = t[--i];//i开始为32,一直减到不为null。这里是确定数组元素的位置i。
entry = e;//找到的元素,hasNext还没有遍历的下一个元素,
index = i;//找到的索引,下一次从i开始检查是否有下一个,
if (e == null) {//上面的while循环退出时候,e=null。没有下一个了。
currentKey = null;
return false;//table中从length开始一个元素都没有,
}
nextKey = e.get(); // e!=null,hasNext还没有遍历的下一个元素的key,
if (nextKey == null)//跳过脏数据
entry = entry.next;//链表的第一个为脏数据,就要沿着链表查找。entry是确定链表的位置。
}
return true;
} protected Entry<K,V> nextEntry() {
//遍历时候返回一个独立的EntryIterator对象,expectedModCount = modCount
//如果遍历时候map被修改了,modCount改变,expectedModCount不会改变,快速失败。
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (nextKey == null && !hasNext())
throw new NoSuchElementException(); lastReturned = entry;//hasNext()确定的下一个还没有访问的entry,
entry = entry.next;//修改entry为下一个没有访问的元素,会是null。null就说明到了链表末尾,就要找数组的下一个元素。
currentKey = nextKey;//设置当前的key,修改nextKey=null,便于进去hasNext()方法,
nextKey = null;
return lastReturned;//返回
} public void remove() {
if (lastReturned == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException(); WeakHashMap1.this.remove(currentKey);
expectedModCount = modCount;
lastReturned = null;
currentKey = null;
}
} private class ValueIterator extends HashIterator<V> {//遍历value的遍历器
public V next() {
return nextEntry().value;
}
} private class KeyIterator extends HashIterator<K> {//遍历key的遍历器
public K next() {
return nextEntry().getKey();
}
} private class EntryIterator extends HashIterator<Map.Entry<K,V>> {//遍历整个map的遍历器
public Map.Entry<K,V> next() {//遍历整个map
return nextEntry();
}
}
//遍历时候KeySet,Values,EntrySet返回的是KeyIterator,ValueIterator,EntryIterator。Set都是调用Iterator的方法来遍历的。
//KeyIterator,ValueIterator,EntryIterator的 next方法都是用的父类HashIterator的 next方法。
//KeySet,Values,EntrySet的方法都是WeakHashMap的方法。
private class KeySet extends AbstractSet<K> {//key的集合。集合里面有遍历器。继承于AbstractSet,说明该集合中没有重复的Key。
public Iterator<K> iterator() {
return new KeyIterator();//key的遍历器
} public int size() {
return WeakHashMap1.this.size();
} public boolean contains(Object o) {
return containsKey(o);
} public boolean remove(Object o) {
if (containsKey(o)) {
WeakHashMap1.this.remove(o);
return true;
}
else
return false;
} public void clear() {
WeakHashMap1.this.clear();
} public Spliterator<K> spliterator() {
return new KeySpliterator<>(WeakHashMap1.this, 0, -1, 0, 0);
}
} private class Values extends AbstractCollection<V> {//value的集合。集合里面有遍历器。Values中的元素能够重复。
public Iterator<V> iterator() {
return new ValueIterator();//value的遍历器
} public int size() {
return WeakHashMap1.this.size();
} public boolean contains(Object o) {
return containsValue(o);
} public void clear() {
WeakHashMap1.this.clear();
} public Spliterator<V> spliterator() {
return new ValueSpliterator<>(WeakHashMap1.this, 0, -1, 0, 0);
}
} private class EntrySet extends AbstractSet<Map.Entry<K,V>> {//map转换为Set的集合。Entry的集合。集合里面有遍历器。遍历map就是这个集合和遍历器。继承于AbstractSet,说明该集合中没有重复的EntrySet。
public Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();//Entry的遍历器
} public boolean contains(Object o) {//调用的是map的方法
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
Entry<K,V> candidate = getEntry(e.getKey());
return candidate != null && candidate.equals(e);
} public boolean remove(Object o) {//调用的是map的方法
return removeMapping(o);
} public int size() {//调用的是map的方法
return WeakHashMap1.this.size();
} public void clear() {//调用的是map的方法
WeakHashMap1.this.clear();
} private List<Map.Entry<K,V>> deepCopy() {//WeakHashMap中的全部元素都拷贝到List中
List<Map.Entry<K,V>> list = new ArrayList<>(size());
for (Map.Entry<K,V> e : this)//this是EntrySet
list.add(new AbstractMap.SimpleEntry<>(e));
return list;
} public Object[] toArray() {
return deepCopy().toArray();//List的转换数组方法
} public <T> T[] toArray(T[] a) {
return deepCopy().toArray(a);
} public Spliterator<Map.Entry<K,V>> spliterator() { return new EntrySpliterator<>(WeakHashMap1.this, 0, -1, 0, 0);
}
}
//-------------------------------3个Spliterator,分割器-------------------------------------------------
//类似于其他散列拆分器的形式,但跳过死元素。
static class WeakHashMapSpliterator<K,V> {
final WeakHashMap1<K,V> map;
WeakHashMap1.Entry<K,V> current; // 当前数组元素-链表的节点
int index; // 数组开始位置
int fence; // 数组结束位置
int est; // 所有链表节点个数,
int expectedModCount; // 修改次数 WeakHashMapSpliterator(WeakHashMap1<K,V> 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) {
WeakHashMap1<K,V> m = map;
est = m.size();//大小,所有链表节点个数,
expectedModCount = m.modCount;
hi = fence = m.table.length;//数组大小
}
return hi;
} public final long estimateSize() {
getFence();
return (long) est;
}
} static final class KeySpliterator<K,V> extends WeakHashMapSpliterator<K,V> implements Spliterator<K> {
KeySpliterator(WeakHashMap1<K,V> m, int origin, int fence, int est, int expectedModCount) {
super(m, origin, fence, est, expectedModCount);//数组开始位置,数组结束位置,链表节点个数,修改次数。
} public KeySpliterator<K,V> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
return (lo >= mid) ? null :
new KeySpliterator<K,V>(map, lo, index = mid, est >>>= 1,
expectedModCount);//分割前一半数组出去,
} public void forEachRemaining(Consumer<? super K> action) {
int i, hi, mc;
if (action == null)
throw new NullPointerException();
WeakHashMap1<K,V> m = map;
WeakHashMap1.Entry<K,V>[] tab = m.table;
if ((hi = fence) < 0) {
mc = expectedModCount = m.modCount;
hi = fence = tab.length;//fence只能为table.length
}
else
mc = expectedModCount;
if (tab.length >= hi && (i = index) >= 0 &&
(i < (index = hi) || current != null)) {//i等于index,index等于length
WeakHashMap1.Entry<K,V> p = current;
current = null; // exhaust
do {
if (p == null)//遍历一个数组的开头
p = tab[i++];//p=tab[0],p=tab[1],,,,p=tab[hi-1],
else {//遍历这个链表
Object x = p.get();//得到key
p = p.next;
if (x != null) {
K k = (K) WeakHashMap1.unmaskNull(x);
action.accept(k);
}
}
} while (p != null || i < hi);//数组没有遍历完,或者链表没遍历完。
}
if (m.modCount != mc)
throw new ConcurrentModificationException();
} public boolean tryAdvance(Consumer<? super K> action) {
int hi;
if (action == null)
throw new NullPointerException();
WeakHashMap1.Entry<K,V>[] tab = map.table;
if (tab.length >= (hi = getFence()) && index >= 0) {
while (current != null || index < hi) {//从数组0到末尾。 数组没有遍历完,或者链表没遍历完。
if (current == null)//遍历数组
current = tab[index++];
else {//遍历链表
Object x = current.get();
current = current.next;
if (x != null) {
K k = (K) WeakHashMap1.unmaskNull(x);
action.accept(k);
if (map.modCount != expectedModCount)//快速失败
throw new ConcurrentModificationException();
return true;
}
}
}
}
return false;
} public int characteristics() {
return Spliterator.DISTINCT;
}
} static final class ValueSpliterator<K,V> extends WeakHashMapSpliterator<K,V> implements Spliterator<V> {
ValueSpliterator(WeakHashMap1<K,V> m, int origin, int fence, int est, int expectedModCount) {
super(m, origin, fence, est, expectedModCount);
} public ValueSpliterator<K,V> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
return (lo >= mid) ? null :
new ValueSpliterator<K,V>(map, lo, index = mid, est >>>= 1, expectedModCount);
} public void forEachRemaining(Consumer<? super V> action) {
int i, hi, mc;
if (action == null)
throw new NullPointerException();
WeakHashMap1<K,V> m = map;
WeakHashMap1.Entry<K,V>[] 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)) {
WeakHashMap1.Entry<K,V> p = current;//当前正在遍历的元素
current = null; // exhaust
do {
if (p == null)
p = tab[i++];
else {
Object x = p.get();
V v = p.value;//得到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<? super V> action) {
int hi;
if (action == null)
throw new NullPointerException();
WeakHashMap1.Entry<K,V>[] 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;
}
} static final class EntrySpliterator<K,V> extends WeakHashMapSpliterator<K,V> implements Spliterator<Map.Entry<K,V>> {
EntrySpliterator(WeakHashMap1<K,V> m, int origin, int fence, int est, int expectedModCount) {
super(m, origin, fence, est, expectedModCount);
} public EntrySpliterator<K,V> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
return (lo >= mid) ? null :
new EntrySpliterator<K,V>(map, lo, index = mid, est >>>= 1,
expectedModCount);
} public void forEachRemaining(Consumer<? super Map.Entry<K, V>> action) {
int i, hi, mc;
if (action == null)
throw new NullPointerException();
WeakHashMap1<K,V> m = map;
WeakHashMap1.Entry<K,V>[] 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)) {
WeakHashMap1.Entry<K,V> 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) WeakHashMap1.unmaskNull(x);
action.accept(new AbstractMap.SimpleImmutableEntry<K,V>(k, v));
}
}
} while (p != null || i < hi);//数组没有遍历完,或者链表没遍历完。
}
if (m.modCount != mc)
throw new ConcurrentModificationException();
} public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
int hi;
if (action == null)
throw new NullPointerException();
WeakHashMap1.Entry<K,V>[] 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) WeakHashMap1.unmaskNull(x);
action.accept(new AbstractMap.SimpleImmutableEntry<K,V>(k, v));
if (map.modCount != expectedModCount)
throw new ConcurrentModificationException();
return true;
}
}
}
}
return false;
} public int characteristics() {
return Spliterator.DISTINCT;
}
}
}
public abstract class AbstractMap1<K,V> implements Map<K,V> {
protected AbstractMap1() {
}
public int size() {
return entrySet().size();//entrySet()抽象方法
}
public boolean isEmpty() {
return size() == 0;
} public boolean containsValue(Object value) {
Iterator<Entry<K,V>> i = entrySet().iterator();//entrySet()抽象方法
if (value==null) {//containsValue value为null的。
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getValue()==null)
return true;
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (value.equals(e.getValue()))
return true;
}
}
return false;
} public boolean containsKey(Object key) {
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
if (key==null) {//containsKey key为null的。
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return true;
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return true;
}
}
return false;
} public V get(Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (key==null) {//get key为null的。
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return e.getValue();
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return e.getValue();
}
}
return null;
} public V put(K key, V value) {//子类实现
throw new UnsupportedOperationException();
} public V remove(Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
Entry<K,V> correctEntry = null;
if (key==null) {//remove key为null的。
while (correctEntry==null && i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
correctEntry = e;
}
} else {
while (correctEntry==null && i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
correctEntry = e;
}
} V oldValue = null;
if (correctEntry !=null) {
oldValue = correctEntry.getValue();
i.remove();
}
return oldValue;
} public void putAll(Map<? extends K, ? extends V> m) {
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
put(e.getKey(), e.getValue());
} public void clear() {
entrySet().clear();
}
public abstract Set<Entry<K,V>> entrySet();//Entry的集合
transient Set<K> keySet;
transient Collection<V> values; public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {//初始化keySet
ks = new AbstractSet<K>() {//返回匿名对象
public Iterator<K> iterator() {//for遍历方法
return new Iterator<K>() {//返回匿名对象
private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() {
return i.hasNext();
} public K next() {
return i.next().getKey();
} public void remove() {
i.remove();
}
};
} public int size() {//大小方法
return AbstractMap1.this.size();
} public boolean isEmpty() {
return AbstractMap1.this.isEmpty();
} public void clear() {
AbstractMap1.this.clear();
} public boolean contains(Object k) {//包含方法
return AbstractMap1.this.containsKey(k);
}
};
keySet = ks;
}
return ks;
} public Collection<V> values() {
Collection<V> vals = values;
if (vals == null) {//初始化values
vals = new AbstractCollection<V>() {//返回匿名对象
public Iterator<V> iterator() {//for遍历方法
return new Iterator<V>() {//返回匿名对象
private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() {
return i.hasNext();
} public V next() {
return i.next().getValue();
} public void remove() {
i.remove();
}
};
} public int size() {
return AbstractMap1.this.size();
} public boolean isEmpty() {
return AbstractMap1.this.isEmpty();
} public void clear() {
AbstractMap1.this.clear();
} public boolean contains(Object v) {
return AbstractMap1.this.containsValue(v);
}
};
values = vals;
}
return vals;
} public boolean equals(Object o) {//2个map中每个元素是不是都相等
if (o == this)
return true;
if (!(o instanceof Map))
return false;
Map<?,?> m = (Map<?,?>) o;
if (m.size() != size())
return false;
try {
Iterator<Entry<K,V>> i = entrySet().iterator();//entrySet()返回EntrySet,iterator()返回EntryIterator。集合里面有遍历器。
while (i.hasNext()) {//hasNext是父类HashIterator的方法
Entry<K,V> e = i.next();//hasNext是父类HashIterator的方法
K key = e.getKey();
V value = e.getValue();
if (value == null) {
if (!(m.get(key)==null && m.containsKey(key))) //m没有key
return false;
} else {
if (!value.equals(m.get(key))) //value不为null,就看value是否相等。
return false;
}
}
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
return true;
} public int hashCode() {
int h = 0;
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return h;
} public String toString() {
Iterator<Entry<K,V>> i = entrySet().iterator();//entrySet()返回EntrySet,iterator()返回EntryIterator。集合里面有遍历器。
if (! i.hasNext())
return "{}"; StringBuilder sb = new StringBuilder();
sb.append('{');
for (;;) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (! i.hasNext())
return sb.append('}').toString();
sb.append(',').append(' ');
}
} protected Object clone() throws CloneNotSupportedException {
AbstractMap1<?,?> result = (AbstractMap1<?,?>)super.clone();//native方法
result.keySet = null;
result.values = null;
return result;
} private static boolean eq(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
} public static class SimpleEntry<K,V> implements Entry<K,V>, java.io.Serializable{
private static final long serialVersionUID = -8499721149061103585L;
private final K key;
private V value; public SimpleEntry(K key, V value) {
this.key = key;
this.value = value;
}
public SimpleEntry(Entry<? extends K, ? extends V> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
}
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
return eq(key, e.getKey()) && eq(value, e.getValue());
}
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
public String toString() {
return key + "=" + value;
}
} public static class SimpleImmutableEntry<K,V> implements Entry<K,V>, java.io.Serializable{
private static final long serialVersionUID = 7138329143949025153L;
private final K key;
private final V value; public SimpleImmutableEntry(K key, V value) {
this.key = key;
this.value = value;
}
public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
public V setValue(V value) {
throw new UnsupportedOperationException();
}
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
return eq(key, e.getKey()) && eq(value, e.getValue());
}
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
public String toString() {
return key + "=" + value;
}
}
}
WeakhashMap源码2的更多相关文章
- WeakhashMap源码1
弱引用(WeakReference)的特性是:当gc线程发现某个对象只有弱引用指向它,那么就会将其销毁并回收内存.WeakReference也会被加入到引用队列queue中. 它的特殊之处在于 Wea ...
- Java WeakHashMap 源码解析
前面把基于特定数据结构的Map介绍完了,它们分别利用了相应数据结构的特点来实现特殊的目的,像HashMap利用哈希表的快速插入.查找实现O(1)的增删改查,TreeMap则利用了红黑树来保证key的有 ...
- 死磕 java集合之WeakHashMap源码分析
欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 WeakHashMap是一种弱引用map,内部的key会存储为弱引用,当jvm gc的时 ...
- WeakHashMap源码解读
1. 简介 本文基于JDK8u111的源码分析WeakHashMap的一些主要方法的实现. 2. 数据结构 就数据结构来说WeakHashMap与HashMap原理差不多,都是拉链法来解决哈希冲突. ...
- WeakHashMap源码分析
WeakHashMap是一种弱引用map,内部的key会存储为弱引用, 当jvm gc的时候,如果这些key没有强引用存在的话,会被gc回收掉, 下一次当我们操作map的时候会把对应的Entry整个删 ...
- WeakHashMap 源码分析
WeakHashMap WeakHashMap 能解决什么问题?什么时候使用 WeakHashMap? 1)WeakHashMap 是基于弱引用键实现 Map 接口的哈希表.当内存紧张,并且键只被 W ...
- Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例
概要 这一章,我们对WeakHashMap进行学习.我们先对WeakHashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用WeakHashMap.第1部分 WeakHashMap介绍 ...
- JDK源码分析(9)之 WeakHashMap 相关
平时我们使用最多的数据结构肯定是 HashMap,但是在使用的时候我们必须知道每个键值对的生命周期,并且手动清除它:但是如果我们不是很清楚它的生命周期,这时候就比较麻烦:通常有这样几种处理方式: 由一 ...
- WeakHashMap,源码解读
概述 WeakHashMap也是Map接口的一个实现类,它与HashMap相似,也是一个哈希表,存储key-value pair,而且也是非线程安全的.不过WeakHashMap并没有引入红黑树来尽量 ...
随机推荐
- 我是如何一步步编码完成万仓网ERP系统的(七)产品库设计 3.品牌图片跨域上传
https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...
- VirtualBox安装Ubuntu-18.04-Server笔记
准备 安装'Windows Terminal' 安装WSL 安装VirtualBox 安装 虚拟磁盘映像文件选择创建在SSD(如果有) 选择openssh,公钥从GitHub获取,前提是GitHub已 ...
- python高级编程——线程和线程池
线程模块 线程的特点: 本质上是异步的.需要多个并发活动.每个活动的处理顺序可能是不确定的.或者说是随机的,不可预测的,宏观上是同时运行的 ...
- [Vscode插件] 自动编译项目中的Sass文件为CSS
插件名 : Live Sass Compiler 今天在VSCode中发现了一个自动watch项目目录下sass文件的插件,摆脱了在控制台中进行手动watch的繁琐. 安装好以后点击右下角即可自动编译 ...
- 使用Dictionary键值对判断字符串中字符出现次数
介绍Dictionary 使用前需引入命名空间 using System.Collections.Generic Dictionary里面每一个元素都是一个键值对(由两个元素组成:键和值) 键必须是唯 ...
- linux安装包制作
1. 常见安装包 打包或压缩文件tar,zip,gz等,一般解压后即可 管理工具的deb,rpm等.这类安装文件可以通过第三方的命令安装 (apt和yum) .bin类,其实就是把sh和zip打包为b ...
- 【转】Git使用教程之基础篇
Git使用教程 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是 ...
- Linux的DNS实现负载均衡及泛域名部署
DNS负载均衡技术的实现原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到 ...
- 交叉编译支持SVE ACLE的gcc
最近在学习AArch64的SVE技术时,发现目前可以在网上找到的gcc版本都不支持SVE intrinsic方式调用,在看文档时发现,GCC要到2020年的GCC10时才会支持: 在github上看到 ...
- 08-人脸识别-FaceNet-classify.py代码阅读(说明见注释)
"""An example of how to use your own dataset to train a classifier that recognizes pe ...