原因:
keySet其實是遍歷了2次,一次是轉(zhuǎn)為Iterator對象,另一次是從hashMap中取出key所對應(yīng)的value。而entrySet只是遍歷了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。
一. keySet和entrySet
1
2
3
4
5
6
7
8
9
10
|
Map<String, String> map = new HashMap<String, String>(); int num = 5000000 ; String key, value; // 存放500萬條數(shù)據(jù) for ( int i = 1 ; i <= num; i++) { key = "" + i; value = "value" ; map.put(key, value); } |
1.1 基本用法
keySet:
1
2
3
4
5
6
7
8
9
|
Map map= new HashMap(); Iterator it=map.keySet().iterator(); Object key; Object value; while (it.hasNext()){ key=it.next(); value=map.get(key); System.out.println(key+ ":" +value); } |
時間:只獲取key 50;獲取key和value 170
entrySet:
1
2
3
4
5
6
7
8
9
10
|
Map map= new HashMap(); Iterator it=map.entrySet().iterator(); Object key; Object value; while (it.hasNext()){ Map.Entry entry = (Map.Entry)it.next(); key=entry.getKey(); value=entry.getValue(); System.out.println(key+ "=" +value); } |
時間:只獲取key或獲取value 時間差不多 110-140;獲取key和value 140
源碼上看:
keySet:
1
2
3
4
|
final class KeyIterator extends HashIterator implements Iterator<K> { public final K next() { return nextNode().key; } } |
entrySet:
1
2
3
4
|
final class EntryIterator extends HashIterator implements Iterator<Map.Entry<K,V>> { public final Map.Entry<K,V> next() { return nextNode(); } } |
其實這里已經(jīng)很明顯了,當(dāng)要得到某個value時,keySet還需要從HashMap中g(shù)et,entrySet相比keySet少了遍歷table的過程,這也是兩者性能上的主要差別。
1
2
3
|
for (String key1 : map.keySet()) { value = map.get(key1); } |
時間:170
1
2
3
4
|
for (Entry<String, String> entry1 : map.entrySet()) { key = entry1.getKey(); value = entry1.getValue(); } |
時間:130
比較:keySet其實是遍歷了2次,一次是轉(zhuǎn)為Iterator對象,另一次是從hashMap中取出key所對應(yīng)的value。而entrySet只是遍歷了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。
二. Map.foreach
在JDK8以后,引入了Map.foreach。
Map.foreach本質(zhì)仍然是entrySet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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); } } |
配合lambda表達(dá)式一起使用,操作起來更加方便。
2.1 使用Java8的foreach+lambda表達(dá)式遍歷Map
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
Map<String, Integer> items = new HashMap<>(); items.put( "A" , 10 ); items.put( "B" , 20 ); items.put( "C" , 30 ); items.put( "D" , 40 ); items.put( "E" , 50 ); items.put( "F" , 60 ); items.forEach((k,v)->System.out.println( "Item : " + k + " Count : " + v)); items.forEach((k,v)->{ System.out.println( "Item : " + k + " Count : " + v); if ( "E" .equals(k)){ System.out.println( "Hello E" ); } }); |
時間:158
到此這篇關(guān)于Java8 HashMap遍歷方式性能探討的文章就介紹到這了,更多相關(guān)Java8 HashMap遍歷方式性能內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://my.oschina.net/hosee/blog/1488876