仅当映射包含给定键时,我才想使用给定键的映射值来做某事。天真地我会写:
Map<String, String> myMap = ...;
if(myMap.containsKey(key)) {
String value = myMap.get(key);
// Do things with value
}
上面的代码看起来很容易理解,但是从性能的角度来看,下面的代码不是更好吗?
Map<String, String> myMap = ...;
String value = myMap.get(key);
if(value != null) {
// Do things with value
}
在第二个片段中,我不喜欢 value
声明的范围更广。
相对于 Map 实现,给定案例的性能如何变化?
注意:我们假设 map 中不允许使用空值。我在这里不是在谈论渐近复杂性,这对两个片段都是一样的
最佳答案
Map
是一个接口(interface),因此实现类在如何实现每个操作方面有相当大的自由度(完全可以编写一个缓冲最后一个条目的类,这可能允许常数时间如果它与上次获取的对象相同,则访问 get
操作,这使得两者实际上等同,除了可能需要的比较之外)。
例如,对于TreeMap
和HashMap
,containsKey
本质上只是一个get
操作(更具体地说是getEntry
) 并检查是否为 null
。
因此,对于这两个容器,第一个版本的时间应该是第二个版本的大约两倍(假设您在两种情况下使用相同类型的 Map
)。
请注意,HashMap.get
的复杂度为 O(1)(具有非常适合数据的散列函数),而 TreeMap.get
的复杂度为 O(log n)。因此,如果您在循环中执行大量工作,并且 Map
不包含数百万个元素,性能差异可能可以忽略不计.
但是,请注意 the docs 中的免责声明对于 Map.get
:
If this map permits null values, then a return value of null does not necessarily indicate that the map contains no mapping for the key; it's also possible that the map explicitly maps the key to null. The containsKey operation may be used to distinguish these two cases.
关于java - map 查找性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18535088/