1. 程式人生 > >map遍歷的幾種方式和效率問題

map遍歷的幾種方式和效率問題

一、map遍歷的效率

先建立一個map,新增好資料:

Map<String, String> map = new HashMap<>();
for (int i = 0; i < 1000000; i++) {
    map.put(i + "", i + "AA");
}
  • 1
  • 2
  • 3
  • 4

1、keySet的for迴圈方式:

//只獲取key
public static void keySetForGetKey(Map<String, String> map){
    long startTime = System.currentTimeMillis();
    for (String key : map.keySet()) {
    }
    long endTime = System.currentTimeMillis();
    System.out.println("keySetForGetKey執行時間" + (endTime - startTime));
}
//獲取key和value
public static void keySetForGetKeyAndValue(Map<String, String> map){
    long startTime = System.currentTimeMillis();
    for (String key : map.keySet()) {
        String value = map.get(key);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("keySetForGetKeyAndValue執行時間" + (endTime - startTime));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2、keySet的iterator迭代器方式:

//只獲取key
public static void keySetIteratorGetKey(Map<String, String> map){
    long startTime = System.currentTimeMillis();
    Iterator<String> iterator = map.keySet().iterator();
    while (iterator.hasNext()) {
        String key = iterator.next();
    }
    long endTime = System.currentTimeMillis();
    System.out.println("keySetIteratorGetKey執行時間" + (endTime - startTime));
}
//獲取key和value
public static void keySetIteratorGetKeyAndValue(Map<String, String> map){
    long startTime = System.currentTimeMillis();
    Iterator<String> iterator = map.keySet().iterator();
    while (iterator.hasNext()) {
        String key = iterator.next();
        String value = map.get(iterator.next());
    }
    long endTime = System.currentTimeMillis();
    System.out.println("keySetIteratorGetKeyAndValue執行時間" + (endTime - startTime));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

3、entrySet的for迴圈方式:

//只獲取key
public static void entrySetForGetKey(Map<String, String> map){
    long startTime = System.currentTimeMillis();
    for (Entry<String, String> entry : map.entrySet()) {
        String key = entry.getKey();
    }
    long endTime = System.currentTimeMillis();
    System.out.println("entrySetForGetKey執行時間" + (endTime - startTime));
}
//獲取key和value
public static void entrySetForGetKeyAndValue(Map<String, String> map){
    long startTime = System.currentTimeMillis();
    for (Entry<String, String> entry : map.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
    }
    long endTime = System.currentTimeMillis();
    System.out.println("entrySetForGetKeyAndValue執行時間" + (endTime - startTime));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

4、entrySet的iterator迭代器方式:

//只獲取key
public static void entrySetIteratorGetKey(Map<String, String> map){
    long startTime = System.currentTimeMillis();
    Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
    while (iterator.hasNext()) {
        String key = iterator.next().getKey();
    }
    long endTime = System.currentTimeMillis();
    System.out.println("entrySetIteratorGetKey執行時間" + (endTime - startTime));
}
//獲取key和value
public static void entrySetIteratorGetKeyAndValue(Map<String, String> map){
    long startTime = System.currentTimeMillis();
    Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
    while (iterator.hasNext()) {
        String key = iterator.next().getKey();
        String value = iterator.next().getValue();
    }
    long endTime = System.currentTimeMillis();
    System.out.println("entrySetIteratorGetKeyAndValue執行時間" + (endTime - startTime));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

最終的執行結果為:

keySetForGetKey執行時間28
keySetForGetKeyAndValue執行時間43
keySetIteratorGetKey執行時間25
keySetIteratorGetKeyAndValue執行時間36
entrySetForGetKey執行時間27
entrySetForGetKeyAndValue執行時間28
entrySetIteratorGetKey執行時間25
entrySetIteratorGetKeyAndValue執行時間29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

總結:

  • entrySet的方式整體都是比keySet方式要高一些;
  • 單純的獲取key來說,兩者的差別並不大,但是如果要獲取value,還是entrySet的效率會更好,因為keySet需要從map中再次根據key獲取value,而entrySet一次都全部獲取出來;
  • iterator的迭代器方式比foreach的效率高。

二、foreach和iterator

其實foreach的語法只是對iterator進行了簡單的包裝,使用起來更加方便而已,但是如果在foreach迴圈體內,對集合元素進行刪除新增操作的時候,會報出ConcurrentModificationException,併發修改異常。如果需要在遍歷集合的時候物件集合中元素進行刪除操作,需要使用iterator的遍歷方式,iterator自帶的remove刪除方式不會報出異常。