Java中的WeakHashMap keySet()方法
Java中的WeakHashMap是一种支持弱引用的哈希表。其中,WeakHashMap的key被自动包装成“弱引用”,被显式或隐式地置为null后,key所对应的键值对会被垃圾回收器回收。WeakHashMap通常用来为对象的高速缓存提供支持。keySet()方法是WeakHashMap类中的一个重要方法,其目的是返回WeakHashMap实例中的所有key组成的Set。
Java中的WeakHashMap
WeakHashMap是Java中支持弱引用清理的哈希表,继承自AbstractMap类。WeakHashMap中的key被自动包装成“弱引用”,也就是说WeakHashMap不会长期持有对key的引用,一旦没有强引用指向key所对应的对象,垃圾回收器就会回收包装key的引用。WeakHashMap通过实现WeakReference类来实现弱引用功能,这个类会起到一个‘重量级’的作用,因此WeakHashMap的性能并不比HashMap好,但WeakHashMap可以长期保存对象实例的引用。
keySet()方法
keySet()方法是Java中的WeakHashMap类中的一个重要方法。该方法返回WeakHashMap实例对应的所有key组成的Set。
/**
* Returns a set view of the keys contained in this map. The set is
* backed by the map, so changes to the map are reflected in the set, and
* vice-versa. If the map is modified while an iteration over the set is
* in progress (except through the iterator's own <tt>remove</tt>
* operation), the results of the iteration are undefined. The set
* supports element removal, which removes the corresponding mapping
* from the map, via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
*
* @return a set view of the keys contained in this map
*/
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}
函数的返回值是WeakHashMap中键的集合,类型为Set。还可以看到,如果keySet不为空,则返回keySet;否则,会新建一个KeySet对象返回。
使用示例
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
public class WeakHashMapDemo {
public static void main(String[] args) throws InterruptedException {
Map<Data, String> map = new WeakHashMap<>();
Data data = new Data();
map.put(data, "info");
Set<Data> keySet = map.keySet();
System.out.println("WeakHashMap keySet: " + keySet);
// 将data对象置为null,使其没有强引用指向data所对应的键值对
data = null;
System.gc();
Thread.sleep(1000);
keySet = map.keySet();
System.out.println("WeakHashMap keySet after gc: " + keySet);
}
private static class Data {
@Override
protected void finalize() throws Throwable {
System.out.println("Data gc");
super.finalize();
}
}
}
在上述实例中,首先创建了一个WeakHashMap实例,并将一个Data对象及其信息存入了该实例中。接着,使用keySet()方法获取WeakHashMap实例中包含的所有key,并输出。
为测试WeakHashMap的gc功能,程序将Data对象置为null,并调用gc函数,等待gc线程进行回收(GC时的打印语句可供参考),最后再输出集合元素观察其变化。
执行结果如下:
WeakHashMap keySet: [weakdemo.WeakHashMapDemo$Data@3d64447d]
Data gc
WeakHashMap keySet after gc: []
结果表明,当Data对象没有被其他强引用指向时,WeakHashMap实例中的键值对会被垃圾回收器回收,此时keySet()方法返回的集合将不再包含已被回收的键值对。
结论
Java中的WeakHashMap keySet()方法可以用来获取WeakHashMap实例中所有key所组成的集合。由于WeakHashMap中的弱引用机制会造成对象的回收,因此使用keySet()方法返回的集合中可能会出现已被回收的键值对。尤其是在程序内存占用极大且机器性能较低的情况下,应当格外注意使用WeakHashMap类及其相关方法。