【问题标题】:Why does exist WeakHashMap, but absent WeakSet?为什么存在WeakHashMap,却没有WeakSet?
【发布时间】:2011-05-03 01:14:55
【问题描述】:

来自J. Bloch

... 内存泄漏的来源是 听众 ... 最好的方法来确保 回调被垃圾收集 及时是只存储弱 对它们的引用,例如,通过 仅将它们作为键存储在 WeakHashMap.

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

【问题讨论】:

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

标签: java collections garbage-collection weak-references


【解决方案1】:

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 创建一组键的类型,而不是值。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 2015-08-13
    • 2014-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多