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


76

J. Bloch

内存泄漏的一个来源是侦听器。确保迅速回收垃圾的最佳方法是仅存储对其的弱引用,例如,仅将它们作为键存储在 WeakHashMap中

那么,为什么Java Collections框架中没有任何WeakSet ?


1
Stas,您能接受mart赞成的,正确的答案,而不是Martin反对的,错误答案吗?
toolforger

尽管Joshua Bloch为Java程序员写了很多合理的建议,但这似乎是一个可怕的例外。将侦听器存储到a中WeakHashMap并不会“确保立即回收垃圾”,而是使它们变得非常不确定。垃圾收集器仅在内存不足时运行,因此,此类弱的侦听器可能会在任意长时间内晃来晃去并仍在执行,但更糟糕的是,此类侦听器在您仍需要它们时可能会虚假地消失,因为它现在需要一个实际上无关紧要的参考资料,以使他们活着。
Holger

Answers:


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

Collections.newSetFromMap文档所示,传递WeakHashMap来获取Set


4
实际上,java集合中的任何Set都包含要存储的Map。
集市

4
是的,但是为什么没有针对此类材料的特定类别?
斯坦·库里林

14
不难想象,为什么java.util的维护者可能想要停止提供他们所做的所有工作的双重Map和Set版本,而是选择仅提供newSetFromMap()……不是吗?
凯文·布劳里恩

24
值得注意的是,在API 9之前的Android中缺少Collections#newSetFromMap了。虽然找到要编译到您的应用程序中的实现并不难,但这是兼容性的陷阱。
nmr 2012年

3
@Mike JavaDoc是正确的。请注意,此答案中的代码返回一组对象而不是布尔值。newSetFromMap创建一组键类型,而不是值。
kabuko,2012年

14

那么,为什么Java收集框架中没有任何WeakSet?

唯一真正正确的答案是,我们不能告诉您原因,因为我们不是做出设计决定的人。只有Java设计师知道他们为什么做出决定1


尽管的用例可能有限WeakHashSet,但Java类库设计理念的一部分是避免针对所有可能的用例用实用程序类填充类库。

还有许多其他类库,其中包括集合类型。Apache Commons Collections和Google Collections(又名Guava)就是很好的例子。但是,WeakHashSet甚至还没有“削减” Apache和Google库。

而且,当然,您可以Collections.newSetFromMap用来包装WeakHashMap实例。


1-辩论该决定的正确性超出了StackOverflow的范围。这是一个问答网站,而不是讨论论坛。


谢谢。可能我需要对其他库进行更多的观察工作才能理解Java收集框架。
斯坦·库里林

“ WeakHashSet的有限用例”?布洛赫博士给您提供了一个非常常见的用例,正如问题中所引用的。
罗勒·布尔克

Bloch引文描述了WeakHashMapnot的用例WeakHashSet。他是否特别提到缺少弱散列集的问题?如果没有,那么你不能要求他作为一个权威要求,这是一个问题。无论如何,这是一个问答,而不是辩论。我只是用Java设计人员通常给出的答案(不包括此类内容)来回答OP的问题。您(或OP)是否同意……仅此而已。
斯蒂芬·C

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.