ChatGPT解决这个技术问题 Extra ChatGPT

Why does exist WeakHashMap, but absent WeakSet?

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?

Stas, can you accept mart's upvoted, correct answer instead of Martin's downvoted, incorrect answer?
While Joshua Bloch wrote a lot of reasonable advice for Java programmers, this seems to be an awful exception. Storing listeners into a 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.

B
Basil Bourque

Collections.newSetFromMap

Set<Object> weakHashSet = 
    Collections.newSetFromMap(
        new WeakHashMap<Object, Boolean>()
    );

As seen in Collections.newSetFromMap documentation, passing a WeakHashMap to get a Set.


actually any Set in java collection contains Map for storing.
Yep, but why there is no specific class for such stuff?
It's easy to imagine why the maintainers of java.util might have wanted to stop having to provide dual Map and Set versions of everything they do, and opted to just provide newSetFromMap() instead... isn't it?
It's worth noting that Collections#newSetFromMap is missing from Android before API 9. It's not difficult to find an implementation to compile into your app, though, but it's a compatibility gotcha.
@Mike The JavaDoc is correct. Note the code in this answer returns a Set of Objects not Booleans. newSetFromMap creates a set of the type of the keys, not the values.
A
Axel Dörfler

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.


if someone is looking for optimizing memory use, the performance are quite better than guava weak interners. docs.geotools.org/stable/javadocs/org/geotools/util/….