为什么在HashMap上调用containsKey
比get
慢?
测试:http://ideone.com/QsWXF(相差> 15%,在sun-jdk-1.6.0.17上运行)
最佳答案
因为它确实可以做更多的工作,所以请参阅the OpenJDK 7 source。
请注意,containsKey
调用getEntry
,而get
直接“进行魔术查找”。我不知道为什么要用这种方法,并且对getForNullKey
的使用/不使用感到更加困惑:参见John B和Ted Hopps的评论。get
对空键进行了早期的代码拆分(请注意,如果条目不存在或存储了空值,则get
将返回null
):
315 if (key == null)
316 return getForNullKey();
...
322 if (e.hash == hash &&
((k = e.key) == key || key.equals(k)))
323 return e.value;
虽然从
getEntry
调用的containsKey
不会拆分为getForNullKey
,但是这里还有其他工作来检查空键大小写(针对链中扫描的每个条目):366 if (e.hash == hash &&
367 ((k = e.key) == key || (key != null && key.equals(k))))
368 return e;
另外,
containsKey
具有附加的条件和方法调用(请注意,即使存储的值为getEntry
,即使存在上述键,null
也会返回Entry对象):352 return getEntry(key) != null;
我想可以认为
containsKey
从“性能”方面受益于具有专门的格式(以减少DRY代码为代价),或者getEntry
可以跟随get
的开头进行早期的空键检查..另一方面,可能有人争辩说get
应该用getEntry
来写;-)快乐的编码。