ChatGPT解决这个技术问题 Extra ChatGPT

为什么存在WeakHashMap,却没有WeakSet?

来自J. Bloch

一个......内存泄漏的来源是监听器......确保回调被及时垃圾收集的最佳方法是仅存储对它们的弱引用,例如,将它们仅作为键存储在 WeakHashMap 中。

那么,为什么 Java Collections framework 中没有 WeakSet?

Stas,你能接受 mart 投赞成票的正确答案,而不是 Martin 投反对票的不正确答案吗?
虽然 Joshua Bloch 为 Java 程序员写了很多合理的建议,但这似乎是一个可怕的例外。将侦听器存储到 WeakHashMap 永远不会“确保回调被迅速收集垃圾”,而是使它们非常不确定。垃圾收集器只会在内存不足的情况下运行,因此,这样的弱监听器可能会在任意长时间内徘徊并且仍然被执行,但更糟糕的是,当你仍然需要时,这样的监听器可能会虚假地消失它们,因为它现在需要一个实际上不相关的强引用来保持它们的活力。

B
Basil Bourque

Collections.newSetFromMap

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

Collections.newSetFromMap 文档中所见,传递 WeakHashMap 以获取 Set


实际上 java 集合中的任何 Set 都包含用于存储的 Map。
是的,但是为什么这些东西没有特定的类呢?
很容易想象为什么 java.util 的维护者可能希望不再提供他们所做的一切的双重 Map 和 Set 版本,而是选择只提供 newSetFromMap() ......不是吗?
值得注意的是,在 API 9 之前的 Android 中缺少 Collections#newSetFromMap。不过,找到编译到您的应用程序中的实现并不难,但这是一个兼容性问题。
@Mike JavaDoc 是正确的。请注意,此答案中的代码返回一组对象而不是布尔值。 newSetFromMap 创建一组键的类型,而不是值。
A
Axel Dörfler

虽然您确实可以使用 Collections.newSetFromMap() 来获取 WeakSet,但它的用例实际上非常有限。

如果您想实现类似 String.intern() 的东西,您可能想看看 Guava 的 Interners.newWeakInterner() 功能。


如果有人正在寻找优化内存使用,性能比番石榴弱实习生要好得多。 docs.geotools.org/stable/javadocs/org/geotools/util/…