diff options
Diffstat (limited to 'qtjava/javalib/org/trinitydesktop/qt/WeakValueMap.java')
-rw-r--r-- | qtjava/javalib/org/trinitydesktop/qt/WeakValueMap.java | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/qtjava/javalib/org/trinitydesktop/qt/WeakValueMap.java b/qtjava/javalib/org/trinitydesktop/qt/WeakValueMap.java new file mode 100644 index 00000000..25989191 --- /dev/null +++ b/qtjava/javalib/org/trinitydesktop/qt/WeakValueMap.java @@ -0,0 +1,68 @@ +/** From Section 12.5.3, Reference Queues page 324-326 + of 'The Java Programming Language, Third Edition'. + + But why wasn't it included in the java.util Collection package? + */ + + +package org.trinitydesktop.qt; + +import java.lang.ref.*; +import java.util.*; + +public class WeakValueMap extends HashMap { + private ReferenceQueue reaped = new ReferenceQueue(); + + private static class ValueRef extends WeakReference { + private final Object key; // key for value + + ValueRef(Object val, Object key, ReferenceQueue q) { + super(val, q); + this.key = key; + } + } + + public Object put(Object key, Object value) { + reap(); + ValueRef vr = new ValueRef(value, key, reaped); + return super.put(key, vr); + } + + public Object get(Object key) { + reap(); + ValueRef vr = (ValueRef) super.get(key); + if (vr == null) { + return null; + } else { + return vr.get(); + } + } + + /** Force an entry to be removed if it is known to be invalid, + rather than waiting for the garbage collector to put it + on the reaped queue. + */ + public Object remove(Object key) { + reap(); + ValueRef vr = (ValueRef) super.get(key); + if (vr == null) { + return null; + } else { + vr.clear(); + super.remove(key); + return null; + } + } + + public int size() { + reap(); + return super.size(); + } + + public void reap() { + ValueRef ref; + while ((ref = (ValueRef) reaped.poll()) != null) { + super.remove(ref.key); + } + } +} |