遍历可以分为上面两种方法,hm.entrySet().iterator()和 hm.keySet().iterator(). entrySet会比keySet快很多。在查资料的时候看到说 hm.entrySet()的时候会拷贝出hashtable中的数据到一个新的Set中,其实不是。
public class IterHashMap {
public static void main(String args[]) {
HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
for (int i = 0; i < 10000; i++) {
hm.put(i, i);
}
Date start = new Date();
System.out.println("****************Method 1***************");
Iterator iter = hm.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<Integer, Integer> entry = (Map.Entry<Integer, Integer>) iter
.next();
System.out.print("Key:" + entry.getKey() + ", Value"
+ entry.getValue() + "\n");
}
Date end = new Date();
System.out.print((end.getTime() - start.getTime()) + "\n");
start = new Date();
System.out.println("****************Method 2***************");
Iterator iterKey = hm.keySet().iterator();
while (iterKey.hasNext()) {
Integer entry = (Integer) iterKey.next();
System.out.print("Key:" + entry + ", Value" + hm.get(entry) + "\n");
}
end = new Date();
System.out.print((end.getTime() - start.getTime()) + "\n");
}
}
HashMap使用了内部类来实现: 下面代码中的table是hashmap中的变量,用来存储数据
private abstract class HashIterator<E> implements Iterator<E> {
final Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if ((next = e.next) == null) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
current = e;
return e;
}
}
可以看到用keyIterator和EntryIterator的唯一区别是keyIterator会调用getKey()获得key,然后返回。
private final class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}
private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}