HashMap的遍历效率讨论
来源:互联网 发布:淘宝虚拟物品有哪些 编辑:程序博客网 时间:2024/06/06 09:13
转自http://hi.baidu.com/injava/item/aac168cd66af7a090bd93a3e
经常遇到对HashMap中的key和value值对的遍历操作,有如下两种方法:
Map<String, String[]> paraMap = new HashMap<String, String[]>();
................
//第一个循环
Set<String> appFieldDefIds = paraMap.keySet();
for (String appFieldDefId : appFieldDefIds) {
String[] values = paraMap.get(appFieldDefId);
......
}
//第二个循环
for(Entry<String, String[]> entry : paraMap.entrySet()){
String appFieldDefId = entry.getKey();
String[] values = entry.getValue();
.......
}
第一种实现明显的效率不如第二种实现。
分析如下 Set<String> appFieldDefIds = paraMap.keySet(); 是先从HashMap中取得keySet
代码如下:
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}
private class KeySet extends AbstractSet<K> {
public Iterator<K> iterator() {
return newKeyIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
return HashMap.this.removeEntryForKey(o) != null;
}
public void clear() {
HashMap.this.clear();
}
}
其实就是返回一个私有类KeySet, 它是从AbstractSet继承而来,实现了Set接口。
再来看看for/in循环的语法
for(declaration : expression)
statement
在执行阶段被翻译成如下各式
for(Iterator<E> #i = (expression).iterator(); #i.hashNext();){
declaration = #i.next();
statement
}
因此在第一个for语句for (String appFieldDefId : appFieldDefIds) 中调用了HashMap.keySet().iterator() 而这个方法调用了newKeyIterator()
Iterator<K> newKeyIterator() {
return new KeyIterator();
}
private class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}
所以在for中还是调用了
在第二个循环for(Entry<String, String[]> entry : paraMap.entrySet())中使用的Iterator是如下的一个内部类
private class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}
此时第一个循环得到key,第二个循环得到HashMap的Entry
效率就是从循环里面体现出来的第二个循环此致可以直接取key和value值
而第一个循环还是得再利用HashMap的get(Object key)来取value值
现在看看HashMap的get(Object key)方法
public V get(Object key) {
Object k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length); //Entry[] table
Entry<K,V> e = table;
while (true) {
if (e == null)
return null;
if (e.hash == hash && eq(k, e.key))
return e.value;
e = e.next;
}
}
其实就是再次利用Hash值取出相应的Entry做比较得到结果,所以使用第一中循环相当于两次进入HashMap的Entry中
而第二个循环取得Entry的值之后直接取key和value,效率比第一个循环高。
其实按照Map的概念来看也应该是用第二个循环好一点,它本来就是key和value的值对,将key和value分开操作在这里不是个好选择。
- HashMap的遍历效率讨论
- HashMap的遍历效率讨论
- hashmap两种遍历效率讨论(转)
- HashMap的遍历效率讨论经常遇到对HashMap中的key和value值对的遍历操作,有如下两种方法:
- HashMap遍历效率测试
- HashMap遍历效率比较
- HashMap的keySet遍历和entrySet遍历时间效率比较
- 遍历HashMap的两种方法及效率
- HashMap的四种遍历方法,及效率比较
- java HashMap遍历的三种方式以及效率对比
- 关于java中HashMap遍历效率问题
- SQL查询效率的讨论
- 讨论invert函数的效率。
- 关于HashMap的一些讨论
- HashMap遍历使用entrySet的效率真的比keyset高?
- Java中HashMap遍历的两种方式及其效率比较
- HashMap对象的遍历
- HashMap 的遍历
- 玩儿转C语言:数组和指针(1)
- GUI简述
- css3 box-shadow
- 【Boost】date常用方法
- strlen与sizeof的区别
- HashMap的遍历效率讨论
- 程序员情书
- C# 带多项式参数的 CRC16计算
- Ubuntu下ZJU的VPN模块
- 推荐机器学习和计算机视觉大牛
- 结构型模式之 类的适配器、对象适配器 笔记
- Android培训---创建Android工程
- July之题目--“微软亚洲研究院”
- js中2个等号与3个等号的区别