如果有人仍然对详细且有数字支持的答案感兴趣:是的,您应该使用entrySet()
vs.keySet()
以防您遍历整个地图。有关详细数字,请参阅此 Gist。我使用 JMH 为使用 Oracle JDK8 的 Map 的默认实现运行基准测试。
主要发现是:迭代keySet
和重新查询每个键总是有点慢。一旦你有更大的地图,乘数就会变得相当大(例如,对于 aConcurrentSkipListMap
它总是 5-10x;而对于HashMap
s 它不大于 2x 最多有一百万个条目)。
然而,这些仍然是非常小的数字。迭代超过 100 万个条目的最慢方法是使用 a ConcurrentSkipListMap.keySet()
,大约为 500-700 毫秒;而迭代IdentityHashMap.entrySet()
只是 25-30 毫秒,LinkedHashMap.entrySet()
紧随其后的是 40-50 毫秒(不足为奇,因为它有一个LinkedList
内部,这有助于迭代)。作为上述链接要点的概述:
Map type | Access Type | Δ for 1M entries
----------------------+-------------+-----------------
HashMap | .entrySet() | 69-72 ms
HashMap | .keySet() | 86-94 ms
ConcurrentHashMap | .entrySet() | 72-76 ms
ConcurrentHashMap | .keySet() | 87-95 ms
TreeMap | .entrySet() | 101-105 ms
TreeMap | .keySet() | 257-279 ms
LinkedHashMap | .entrySet() | 37-49 ms
LinkedHashMap | .keySet() | 89-120 ms
ConcurrentSkipListMap | .entrySet() | 94-108 ms
ConcurrentSkipListMap | .keySet() | 494-696 ms
IdentityHashMap | .entrySet() | 26-29 ms
IdentityHashMap | .keySet() | 69-77 ms
所以底线是:这取决于您的用例。虽然迭代数字并不大,特别是对于相当小的地图来说,迭代肯定更快。entrySet()
但是,如果您经常迭代具有 100 万个条目的 Map,最好使用更快的方法;)
当然,这些数字只是为了相互比较,而不是绝对的。