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的更多相关文章

  1. WeakhashMap源码1

    弱引用(WeakReference)的特性是:当gc线程发现某个对象只有弱引用指向它,那么就会将其销毁并回收内存.WeakReference也会被加入到引用队列queue中. 它的特殊之处在于 Wea ...

  2. Java WeakHashMap 源码解析

    前面把基于特定数据结构的Map介绍完了,它们分别利用了相应数据结构的特点来实现特殊的目的,像HashMap利用哈希表的快速插入.查找实现O(1)的增删改查,TreeMap则利用了红黑树来保证key的有 ...

  3. 死磕 java集合之WeakHashMap源码分析

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 WeakHashMap是一种弱引用map,内部的key会存储为弱引用,当jvm gc的时 ...

  4. WeakHashMap源码解读

    1. 简介 本文基于JDK8u111的源码分析WeakHashMap的一些主要方法的实现. 2. 数据结构 就数据结构来说WeakHashMap与HashMap原理差不多,都是拉链法来解决哈希冲突. ...

  5. WeakHashMap源码分析

    WeakHashMap是一种弱引用map,内部的key会存储为弱引用, 当jvm gc的时候,如果这些key没有强引用存在的话,会被gc回收掉, 下一次当我们操作map的时候会把对应的Entry整个删 ...

  6. WeakHashMap 源码分析

    WeakHashMap WeakHashMap 能解决什么问题?什么时候使用 WeakHashMap? 1)WeakHashMap 是基于弱引用键实现 Map 接口的哈希表.当内存紧张,并且键只被 W ...

  7. Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例

    概要 这一章,我们对WeakHashMap进行学习.我们先对WeakHashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用WeakHashMap.第1部分 WeakHashMap介绍 ...

  8. JDK源码分析(9)之 WeakHashMap 相关

    平时我们使用最多的数据结构肯定是 HashMap,但是在使用的时候我们必须知道每个键值对的生命周期,并且手动清除它:但是如果我们不是很清楚它的生命周期,这时候就比较麻烦:通常有这样几种处理方式: 由一 ...

  9. WeakHashMap,源码解读

    概述 WeakHashMap也是Map接口的一个实现类,它与HashMap相似,也是一个哈希表,存储key-value pair,而且也是非线程安全的.不过WeakHashMap并没有引入红黑树来尽量 ...

随机推荐

  1. 我是如何一步步编码完成万仓网ERP系统的(七)产品库设计 3.品牌图片跨域上传

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...

  2. VirtualBox安装Ubuntu-18.04-Server笔记

    准备 安装'Windows Terminal' 安装WSL 安装VirtualBox 安装 虚拟磁盘映像文件选择创建在SSD(如果有) 选择openssh,公钥从GitHub获取,前提是GitHub已 ...

  3. python高级编程——线程和线程池

    线程模块           线程的特点:                本质上是异步的.需要多个并发活动.每个活动的处理顺序可能是不确定的.或者说是随机的,不可预测的,宏观上是同时运行的       ...

  4. [Vscode插件] 自动编译项目中的Sass文件为CSS

    插件名 : Live Sass Compiler 今天在VSCode中发现了一个自动watch项目目录下sass文件的插件,摆脱了在控制台中进行手动watch的繁琐. 安装好以后点击右下角即可自动编译 ...

  5. 使用Dictionary键值对判断字符串中字符出现次数

    介绍Dictionary 使用前需引入命名空间 using System.Collections.Generic Dictionary里面每一个元素都是一个键值对(由两个元素组成:键和值) 键必须是唯 ...

  6. linux安装包制作

    1. 常见安装包 打包或压缩文件tar,zip,gz等,一般解压后即可 管理工具的deb,rpm等.这类安装文件可以通过第三方的命令安装 (apt和yum) .bin类,其实就是把sh和zip打包为b ...

  7. 【转】Git使用教程之基础篇

    Git使用教程 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是 ...

  8. Linux的DNS实现负载均衡及泛域名部署

    DNS负载均衡技术的实现原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到 ...

  9. 交叉编译支持SVE ACLE的gcc

    最近在学习AArch64的SVE技术时,发现目前可以在网上找到的gcc版本都不支持SVE intrinsic方式调用,在看文档时发现,GCC要到2020年的GCC10时才会支持: 在github上看到 ...

  10. 08-人脸识别-FaceNet-classify.py代码阅读(说明见注释)

    """An example of how to use your own dataset to train a classifier that recognizes pe ...