sclass WeakCompactHashSet extends AbstractSet { new CompactHashSet> set; new ReferenceQueue queue; sclass MyWeakReference extends WeakReference { int hash; *(A o) { super(o); hash = o.hashCode(); } *(A o, ReferenceQueue queue) { super(o, queue); hash = o.hashCode(); } public int hashCode() { ret hash; } public bool equals(O o) { ret o instanceof MyWeakReference && eq(get(), ((MyWeakReference) o).get()); } } // Make sure we get reaped once a minute (or whatever the policy is) *() { _registerWeakCollection(this); } void reap() { MyWeakReference ref; while ((ref = (MyWeakReference) queue.poll()) != null) set.removeIfSame(ref); } public int size() { reap(); ret set.size(); } public Iterator iterator() { final Iterator> it = set.iterator(); ret iteratorFromFunction(() -> { while (it.hasNext()) { MyWeakReference ref = it.next(); A a = ref.get(); if (a != null) ret a; // todo: clean up entry } null; }); } public bool contains(O o) { reap(); ret set.contains(new MyWeakReference(o)); } public bool add(A a) { reap(); ret set.add(new MyWeakReference(a, queue)); } public bool remove(O o) { reap(); ret set.remove(new MyWeakReference(o)); } A find(O o) { reap(); MyWeakReference ref = set.find(new MyWeakReference(o)); ret ref == null ? null : ref.get(); } }