【问题标题】:Does calling HashMap.entrySet() instantiate and populate a new set every time?每次调用 HashMap.entrySet() 都会实例化并填充一个新集合吗?
【发布时间】:2014-01-28 02:17:46
【问题描述】:

我需要在 OpenGL 循环的每一帧上迭代一些 HashMap。我是这样做的:

for (Map.Entry<MyKey, MyValue> entry : myMap.entrySet(){...}

我担心的是,每次调用entrySet() 时是否会实际实例化并填充一个全新的 Map.Entry 对象,因为如果是这样,在 OpenGL 中制作动画时 GC 会比我想要的更忙.我的直觉说不,因为 HashMap 文档说您可以使用返回的条目集直接修改 HashMap,但我不知道如何确定。

我还想了解其他 Map 实现,例如 Hashtable、TreeMap 和 LinkedHashMap。

【问题讨论】:

  • JDK源码为公开资料,查查即可。
  • 三年过去了,我还不知道!
  • 另外,您的 JDK 安装应该包含一个 src.zip 以及您链接到 IDE 的所有源代码。
  • 奇怪的是,有两个人认为这应该因为太宽泛而被关闭。答案要么是,要么不是。不能比这更广泛。保持开放可能对其他人有所帮助。如果有人曾经在 SO 上问过这个问题,那我可以节省 15 分钟的时间来浏览和理解 HashMap 源代码。

标签: java


【解决方案1】:

查看源代码后,答案是否定的。它懒惰地实例化第一次调用entrySet() 时设置的条目,然后在每次后续调用时返回对同一对象的引用。

LinkedHashMap、Hashtable 和 TreeMap 也是如此。

【讨论】:

    【解决方案2】:

    不,它不会创建一个新的 Set,而是一个轻量级的包装器,例如。 Arrays.asList 可以,API 说 The set is backed by the map, so changes to the map are reflected in the set, and vice-versa.

    【讨论】:

      【解决方案3】:

      HashMap.entrySet 的实现只是一个廉价的视图,每次调用它都需要 O(1) 时间来创建。通过迭代得到的入口对象,实际上就是映射用来实现其内部数据结构的对象。

      (那个,而且真的没有其他方法可以做你想做的事情。)

      【讨论】:

      • 所有这三个答案都提供了补充信息,但这是一种有用的查看方式。就我而言,我不太关心创建时间。只是不想实例化并允许释放许多小对象,因为 GC 会导致动画打嗝。
      猜你喜欢
      • 2020-11-17
      • 2020-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-17
      • 2022-01-23
      • 1970-01-01
      相关资源
      最近更新 更多