Map的keySet()和entrySet()的性能考虑
所有,
有人可以让我确切地知道两者之间的性能问题是什么吗?该网站:CodeRanch 提供了内部的简要概述使用 keySet() 和 get() 时需要的调用。但如果任何人都可以提供有关使用 keySet() 和 get() 方法时流程的确切详细信息,那就太好了。这将帮助我更好地理解性能问题。
All,
Can anyone please let me know exactly what are the performance issues between the 2? The site : CodeRanch provides a brief overview of the internal calls that would be needed when using keySet() and get(). But it would be great if anyone can provide exact details about the flow when keySet() and get() methods are used. This would help me understand the performance issues better.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用entrySet 优于keySet 的最常见情况是当您迭代Map 中的所有键/值对时。
这比
:
因为在第二种情况下,对于 keySet 中的每个键,都会调用
map.get()
方法,在 HashMap 的情况下,该方法要求评估键对象的 >hashCode()
和equals()
方法以找到关联的值*。在第一种情况下,额外的工作就被消除了。编辑:如果您考虑 TreeMap,情况会更糟,其中对 get 的调用是 O(log(n)),即比较器可能需要运行 log2(n) 次(n = Map 的大小)才能找到关联的价值。
*某些 Map 实现具有内部优化,可以在调用
hashCode()
和equals()
之前检查对象的身份。The most common case where using entrySet is preferable over keySet is when you are iterating through all of the key/value pairs in a Map.
This is more efficient:
than:
Because in the second case, for every key in the keySet the
map.get()
method is called, which - in the case of a HashMap - requires that thehashCode()
andequals()
methods of the key object be evaluated in order to find the associated value*. In the first case that extra work is eliminated.Edit: This is even worse if you consider a TreeMap, where a call to get is O(log(n)), i.e. the comparator may need to run log2(n) times (n = size of the Map) before finding the associated value.
*Some Map implementations have internal optimisations that check the objects' identity before the
hashCode()
andequals()
are called.首先,这完全取决于您使用的
地图
类型。但由于 JavaRanch 线程讨论了HashMap
,我假设这就是您所指的实现。我们还假设您正在谈论 Sun/Oracle 的标准 API 实现。其次,如果您在迭代哈希映射时担心性能,我建议您查看
LinkedHashMap
。来自文档:HashMap.entrySet()
此实现的源代码可用。该实现基本上只是返回一个新的
HashMap.EntrySet
。一个类看起来像这样:一个
HashIterator
看起来像这样所以你已经拥有它了...这就是指示当你迭代
entrySet
时会发生什么的代码。它会遍历整个数组,数组的长度与地图的容量一样长。HashMap.keySet() 和 .get()
在这里,您首先需要获取键集。这需要的时间与映射的容量成正比(与
LinkedHashMap
的大小相反)。完成此操作后,您可以为每个键调用一次get()
。当然,在一般情况下,通过良好的 hashCode 实现,这需要恒定的时间。然而,它不可避免地需要大量的hashCode()
和equals()
调用,这显然比仅仅执行entry.value()< /代码> 调用。
First of all, this depends entirely on which type of
Map
you're using. But since the JavaRanch thread talks aboutHashMap
, I'll assume that that's the implementation you're referring to. And let's assume also that you're talking about the standard API implementation from Sun/Oracle.Secondly, if you're concerned about performance when iterating through your hash map, I suggest you have a look at
LinkedHashMap
. From the docs:HashMap.entrySet()
The source-code for this implementation is available. The implementation basically just returns a new
HashMap.EntrySet
. A class which looks like this:and a
HashIterator
looks likeSo there you have it... That's the code dictating what will happen when you iterate through an
entrySet
. It walks through the entire array, which is as long as the map's capacity.HashMap.keySet() and .get()
Here you first need to get hold of the set of keys. This takes time proportional to the capacity of the map (as opposed to size for the
LinkedHashMap
). After this is done, you callget()
once for each key. Sure, in the average case, with a good hashCode-implementation this takes constant time. However, it will inevitably require lots ofhashCode()
andequals()
calls, which will obviously take more time than just doing aentry.value()
call.这是一篇文章的链接,比较
entrySet()
、keySet()
和values()
的性能,以及有关何时使用每种方法的建议。显然,只要您不需要
Map.get() ,使用
keySet()
比entrySet()
更快(而且更方便)值。Here is the link to an article comparing the performance of
entrySet()
,keySet()
andvalues()
, and advice regarding when to use each approach.Apparently the use of
keySet()
is faster (besides being more convenient) thanentrySet()
as long as you don't need toMap.get()
the values.