From J. Bloch
A ... source of memory leaks is listeners ... The best way to ensure that callbacks are garbage collected promptly is to store only weak references to them, for instance, by storing them only as keys in a WeakHashMap.
So, why there isn't any WeakSet in the Java Collections framework?
WeakHashMap
does never “ensure that callbacks are garbage collected promptly”, but rather makes them horribly non-deterministic. The garbage collector will only run when there is insufficient memory, hence, such weak listeners may be dangling around an arbitrary long time and still getting executed, but even worse, such listeners might spuriously disappear when you still need them, as it now needs an actually unrelated strong reference to keep them alive.
Collections.newSetFromMap
Set<Object> weakHashSet =
Collections.newSetFromMap(
new WeakHashMap<Object, Boolean>()
);
As seen in Collections.newSetFromMap
documentation, passing a WeakHashMap
to get a Set
.
While you can indeed use Collections.newSetFromMap()
to get a WeakSet, it's use cases are actually quite limited.
If you want to implement something like String.intern()
you might want to have a look at Guava's Interners.newWeakInterner()
functionality instead.
Success story sharing
newSetFromMap
creates a set of the type of the keys, not the values.