Java集合 WeakHashMap

WeakHashMap和HashMap一样,是一个散列表,存储的内容也是键值对(key-value)映射,键和值都可以为null。区别是WeakHashMap的键是“弱键”(当WeakHashMap某个键不再正常使用时,会被从WeakHashMap自动删除)

WeakHashMap的继承关系

public class WeakHashMap<K,V>
        extends AbstractMap<K,V>
        implements Map<K,V>

向WeakHashMap中添加键值对

private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
    V value;
    final int hash;
    Entry<K, V> next;

    /**
     * 创建新的entry.
     */
    Entry(Object key, V value, ReferenceQueue<Object> queue, int hash, Entry<K, V> next) {
        super(key, queue);
        this.value = value;
        this.hash = hash;
        this.next = next;
    }
    //
}

WeakHashMap是通过数组table保存Entry(键值对);每个Entry实际上就是一个链表来实现的,即就是 Entry是一个键值对链表。

回收key

private final ReferenceQueue<Object> queue = new ReferenceQueue<>();

某“弱键”不再被其它对象引用,就会被GC回收,“弱键”也同时被添加到ReferenceQueue队列中
当需要再操作WeakHashMap时,先同步table、queue,因table中保存了全部的键值对,而queue中保存的是GC回收的键值对,同步就会删除被GC回收的键值对。

put方法

private static Object maskNull(Object key) {
    return (key == null) ? NULL : key;
}
public V put(K key, V value) {
    Object k = maskNull(key);
    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())) {
             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)
        resize(tab.length * 2);
    return null;
}

插入方法:判断key是否为空,若为空则key为NULL,再计算hash值,遍历数组,通过hash查找插入位置,若存在相应hash,覆盖旧值,若不存在,构建Entry对象,再存入数组

get方法:

private static Object maskNull(Object key) {
    return (key == null) ? NULL : key;
}
public V get(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) {
        if (e.hash == h && eq(k, e.get())) return e.value;
        e = e.next;
    }
    return null;
}

查找方法:判断key是否为空,若为空则key为NULL,再计算hash值,遍历数组是否存在相同的hash,是则返回value。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值