【问题标题】:can I use WeakHashMap instead of HashMap我可以使用 Wea​​kHashMap 代替 HashMap
【发布时间】:2015-10-10 03:42:33
【问题描述】:

我正在使用 Java 中的 WeakHashMap。我所理解的是WeakHashMapHashMap 完全相同,只是它的关键引用是WeakReference。这意味着键引用符合gc 的条件,当它被垃圾时,它的条目将从映射中删除。这在HashMap 中不可用。如果我错了,请纠正我。

我在这里有一个问题。

现在将来如果我要求我必须使用 Map 来放置 key 和 value,我可以继续使用 WeakHashMap 吗?或者我是否需要考虑WeakHashMap 不适合只有HashMap 适合的任何情况?

【问题讨论】:

标签: java


【解决方案1】:

您确实需要考虑上下文来决定使用 Wea​​kHashMap 是否正确/安全。

这是一个 WeakHashMap 不起作用的示例(伪代码)

Map<Name, Details> map = ...
do for ever:
    name = get name from user
    if lookup:
        details = map.get(name)
        display details
    else if create:
        details = get details from user
        map.add(name, details)

使用 Wea​​kHashMap,存在条目会从表中删除的风险,并且用户的查找将失败。使用 HashMap,没有风险。


还有一个问题是 WeakReference 和任何基于它构建的东西都比普通的引用更昂贵。他们使用更多的空间和时间。更重要的是,每次 GC 遇到 Reference 类都会产生开销,这会增加 GC 暂停时间。

但是,运行时开销问题通常应该是正确性问题的次要问题。

  • 如果您在应该使用WeakHashMap 的情况下使用HashMap,那么您很可能会遇到堆填满问题。这也存在性能问题。

  • 如果您在应该使用HashMap 的地方使用WeakHashMap,您可能会丢失信息。

【讨论】:

    【解决方案2】:

    在某些情况下WeakHashMap 不会替换 HashMap,例如:

    1. 在调用参数类型为具体类型 HashMap&lt;K, V&gt; 而不是接口类型 Map&lt;K, V&gt; 的 API 时。
    2. 当您的代码假定没有其他东西正在从它下面更改地图时。垃圾收集器可以随时删除弱键,导致 WeakHashMap 方法的行为就像条目刚刚被删除一样。所以例如如果将地图大小放入变量中,实际地图可能会小于枚举时的地图大小。 (有关示例,请参阅 JavaDoc。)将 WeakHashMap 传递给可能未准备好进行此类更改的代码是有风险的。同步无济于事。
    3. 当您不想要额外的空间和时间开销时。

    我建议仅在需要时使用 Wea​​kHashMap(例如侦听器注册表),并且仅在所有涉及它的代码都明确准备好消失条目时使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 2012-08-11
      • 2022-01-23
      • 2012-06-16
      • 2015-08-07
      • 1970-01-01
      相关资源
      最近更新 更多