我可以使用WeakHashMap而不是HashMap

时间:2015-10-10 03:42:33

标签: java

我在Java中经历了WeakHashMap。我所理解的是WeakHashMapHashMap完全相同,但其关键参考是WeakReference。这意味着密钥引用符合gc的条件,当它被攻击时,其条目将从地图中删除。这在HashMap中不可用。如果我错了,请纠正我。

我在这里有一个问题。

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

2 个答案:

答案 0 :(得分:2)

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

以下是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)

使用WeakHashMap,存在条目退出表格的风险,并且用户的查找将失败。使用HashMap,没有风险。

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

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

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

  • 如果您使用WeakHashMap使用HashMap,则可能会丢失信息。

答案 1 :(得分:1)

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

  1. 调用参数类型为具体类型HashMap<K, V>而不是接口类型Map<K, V>的API时。
  2. 当您的代码假设没有其他任何东西正在从它下面改变地图。垃圾收集器可以随时删除弱键,导致WeakHashMap方法就像当时删除了条目一样。所以例如如果将地图大小放入变量中,则实际地图可能小于枚举时的地图。 (有关示例,请参阅JavaDoc。)将WeakHashMap传递给可能无法为此类更改做准备的代码存在风险。同步对此没有帮助。
  3. 当你不想要额外的空间和时间开销时。
  4. 我建议仅在需要时使用WeakHashMap(例如,监听器注册表),并且仅在接触到它的所有代码明确为消失的条目准备时使用。