使用KeySet和EntrySet遍历的差别
1 public static void main(String[] args) { 2 3 HashMap<Integer, Integer> hasMap = new HashMap(); 4 for (int i = 0; i < 10000; i++) { 5 hasMap.put(i, i); 6 } 7 8 Long j = System.currentTimeMillis(); 9 for (int i = 1; i < 100000; i++) { 10 for (Map.Entry<Integer, Integer> integerIntegerEntry : hasMap.entrySet()) { 11 integerIntegerEntry.getKey(); 12 integerIntegerEntry.getValue(); 13 } 14 } 15 System.out.println("使用EntrySet:" + (System.currentTimeMillis() - j)); 16 17 Long k = System.currentTimeMillis(); 18 for (int i = 1; i < 100000; i++) { 19 for (Integer key : hasMap.keySet()) { 20 hasMap.get(key); 21 } 22 } 23 System.out.println("使用KeySet:" + (System.currentTimeMillis() - k)); 24 25 }
运行多次后,两者差别有2秒左右
结论:使用EntrySet遍历时性能更高。《阿里开发手册》中也推荐使用EntrySet
原因分析:。。。
JDK8中Map interface有个default实现方法forEach, 遍历的也是EntrySet
default void forEach(BiConsumer<? super K, ? super V> action) { Objects.requireNonNull(action); for (Map.Entry<K, V> entry : entrySet()) { K k; V v; try { k = entry.getKey(); v = entry.getValue(); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } action.accept(k, v); } }