package org.robobinding.internal.java_beans; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.Map; import org.robobinding.util.Maps; /** * @since 1.0 * @version * @author Cheng Wei */ public class WeakCache<K, V> { private final Map<K, WeakValue<V>> map; private final ReferenceQueue<V> queue; public WeakCache() { map = Maps.newHashMap(); queue = new ReferenceQueue<V>(); } public int size() { return map.size(); } public boolean isEmpty() { return map.isEmpty(); } public boolean containsKey(Object key) { processQueue(); return map.containsKey(key); } public V get(Object key) { return getReferenceObject(map.get(key)); } public V put(K key, V value) { processQueue(); WeakValue<V> oldValue = map.put(key, new WeakValue<V>(key, value, queue)); return getReferenceObject(oldValue); } public Object remove(Object key) { return getReferenceObject(map.remove(key)); } private final V getReferenceObject(WeakReference<V> ref) { return (ref == null) ? null : ref.get(); } @SuppressWarnings("unchecked") private void processQueue() { WeakValue<V> wv = null; while ((wv = (WeakValue<V>) this.queue.poll()) != null) { map.remove(wv.key); } } private static class WeakValue<V> extends WeakReference<V> { private final Object key; public WeakValue(Object key, V value, ReferenceQueue<V> queue) { super(value, queue); this.key = key; } } }