自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java 中九種 Map 的遍歷方式,你一般用的是哪種呢?

開發(fā) 前端
我們可以看到這種方式相對于 map.entrySet() 方式,多了一步 get 的操作,這種場景比較適合我們只需要 key 的場景,如果也需要使用 value 的場景不建議使用 map.keySet() 來進行遍歷,因為會多一步 map.get() 的操作。

日常工作中 Map 絕對是我們 Java 程序員高頻使用的一種數(shù)據(jù)結(jié)構(gòu),那 Map 都有哪些遍歷方式呢?這篇文章阿粉就帶大家看一下,看看你經(jīng)常使用的是哪一種。

通過 entrySet 來遍歷

1、通過 for 和 map.entrySet() 來遍歷

第一種方式是采用 for 和 Map.Entry 的形式來遍歷,通過遍歷 map.entrySet() 獲取每個 entry 的 key 和 value,代碼如下。這種方式一般也是阿粉使用的比較多的一種方式,沒有什么花里胡哨的用法,就是很樸素的獲取 map 的 key 和 value。

public static void testMap1(Map<Integer, Integer> map){
long sum = 0;
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
sum += entry.getKey() + entry.getValue();
}
System.out.println(sum);
}

看過 HashMap 源碼的同學應該會發(fā)現(xiàn),這個遍歷方式在源碼中也有使用,如下圖所示,

圖片

putMapEntries 方法在我們調(diào)用 putAll 方法的時候會用到。

圖片

2、通過 for, Iterator 和 map.entrySet() 來遍歷

我們第一個方法是直接通過 for 和 entrySet() 來遍歷的,這次我們使用 entrySet() 的迭代器來遍歷,代碼如下。

public static void testMap2(Map<Integer, Integer> map){
long sum = 0;
for (Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator(); entries.hasNext(); ) {
Map.Entry<Integer, Integer> entry = entries.next();
sum += entry.getKey() + entry.getValue();
}
System.out.println(sum);
}

3、通過 while,Iterator  和 map.entrySet() 來遍歷

上面的迭代器是使用 for 來遍歷,那我們自然可以想到還可以用 while 來進行遍歷,所以代碼如下所示。

public static void testMap3(Map<Integer, Integer> map){
Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
long sum = 0;
while (it.hasNext()) {
Map.Entry<Integer, Integer> entry = it.next();
sum += entry.getKey() + entry.getValue();
}
System.out.println(sum);
}

這種方法跟上面的方法類似,只不過循環(huán)從 for 換成了 while,日常我們在開發(fā)的時候,很多場景都可以將 for 和 while 進行替換。2 和 3 都使用迭代器 Iterator,通過迭代器的 next(),方法來獲取下一個對象,依次判斷是否有 next。

通過 keySet 來遍歷

上面的這三種方式雖然代碼的寫法不同,但是都是通過遍歷 map.entrySet() 來獲取結(jié)果的,殊途同歸。接下來我們看另外的一組。

4、通過 for 和 map.keySet() 來遍歷

前面的遍歷是通過 map.entrySet() 來遍歷,這里我們通過 map.keySet() 來遍歷,顧名思義前者是保存 entry 的集合,后者是保存 key 的集合,遍歷的代碼如下,因為是 key 的集合,所以如果想要獲取 key 對應的 value 的話,還需要通過 map.get(key) 來獲取。

public static void testMap4(Map<Integer, Integer> map){
long sum = 0;
for (Integer key : map.keySet()) {
sum += key + map.get(key);
}
System.out.println(sum);
}

5、通過 for,Iterator 和 map.keySet() 來遍歷

public static void testMap5(Map<Integer, Integer> map){
long sum = 0;
for (Iterator<Integer> key = map.keySet().iterator(); key.hasNext(); ) {
Integer k = key.next();
sum += k + map.get(k);
}
System.out.println(sum);
}

6、通過 while,Iterator 和 map.keySet() 來遍歷

public static void testMap6(Map<Integer, Integer> map){
Iterator<Integer> it = map.keySet().iterator();
long sum = 0;
while (it.hasNext()) {
Integer key = it.next();
sum += key + map.get(key);
}
System.out.println(sum);
}

我們可以看到這種方式相對于 map.entrySet() 方式,多了一步 get 的操作,這種場景比較適合我們只需要 key 的場景,如果也需要使用 value 的場景不建議使用 map.keySet() 來進行遍歷,因為會多一步 map.get() 的操作。

Java 8 的遍歷方式

注意下面的幾個遍歷方法都是是 JDK 1.8 引入的,如果使用的 JDK 版本不是 1.8 以及之后的版本的話,是不支持的。

7、通過 map.forEach() 來遍歷

JDK 中的 forEach 方法,使用率也挺高的。

public static void testMap7(Map<Integer, Integer> map){
final long[] sum = {0};
map.forEach((key, value) -> {
sum[0] += key + value;
});
System.out.println(sum[0]);
}

該方法被定義在 java.util.Map#forEach 中,并且是通過 default 關(guān)鍵字來標識的,如下圖所示。這里提個問題,為什么要使用 default 來標識呢?歡迎把你的答案寫在評論區(qū)。

圖片

8、Stream 遍歷

public static void testMap8(Map<Integer, Integer> map){
long sum = map.entrySet().stream().mapToLong(e -> e.getKey() + e.getValue()).sum();
System.out.println(sum);
}

9、ParallelStream 遍歷

public static void testMap9(Map<Integer, Integer> map){
long sum = map.entrySet().parallelStream().mapToLong(e -> e.getKey() + e.getValue()).sum();
System.out.println(sum);
}

這兩種遍歷方式都是 JDK 8 的 Stream 遍歷方式,stream 是普通的遍歷,parallelStream 是并行流遍歷,在某些場景會提升性能,但是也不一定。

測試代碼

上面的遍歷方式有了,那么我們在日常開發(fā)中到底該使用哪一種呢?每一種的性能是怎么樣的呢?為此阿粉這邊通過下面的代碼,我們來測試一下每種方式的執(zhí)行時間。

public static void main(String[] args){
int outSize = 1;
int mapSize = 200;
Map<Integer, Integer> map = new HashMap<>(mapSize);
for (int i = 0; i < mapSize; i++) {
map.put(i, i);
}
System.out.println("---------------start------------------");
long totalTime = 0;
for (int size = outSize; size > 0; size--) {
long startTime = System.currentTimeMillis();
testMap1(map);
totalTime += System.currentTimeMillis() - startTime;
}
System.out.println("testMap1 avg time is :" + (totalTime / outSize));
// 省略其他方法,代碼跟上面一致
}

為了避免一些干擾,這里通過外層的 for 來進行多次計算,然后求平均值,當我們的參數(shù)分別是 outSize = 1,mapSize = 200 的時候,測試的結(jié)果如下

圖片

圖片

當隨著我們增大 mapSize 的時候,我們會發(fā)現(xiàn),后面幾個方法的性能是逐漸上升的。

圖片

圖片

總結(jié)

從上面的例子來看,當我們的集合數(shù)量很少的時候,基本上普通的遍歷就可以搞定,不需要使用 JDK 8 的高級 API 來進行遍歷,當我們的集合數(shù)量較大的時候,就可以考慮采用 JDK 8 的 forEach 或者 Stream 來進行遍歷,這樣的話效率更高。在普通的遍歷方法中 entrySet() 的方法要比使用 keySet() 的方法好。

責任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2022-11-17 15:17:12

Java數(shù)據(jù)結(jié)構(gòu)Map

2023-04-08 14:22:16

Spring初始化對象

2023-10-08 08:46:29

Java遍歷方式

2013-04-09 12:41:33

Java Map遍歷法Java

2025-03-26 00:35:25

2010-10-08 14:23:08

MySQL中INSER

2013-01-20 21:55:24

移動策略

2021-12-13 08:29:18

Code編程字體

2024-06-19 19:17:04

2023-10-30 09:46:08

接口重試技巧

2020-10-26 14:03:07

混合云云計算云遷移

2020-06-09 08:09:07

機器學習統(tǒng)計學習無監(jiān)督學習

2018-01-08 15:07:15

java項目后臺

2016-12-19 14:35:10

機器人工作

2020-04-08 15:59:23

顯卡Linux命令

2012-07-25 14:25:08

PrismPrism4MVVM

2010-02-04 17:49:04

C++參數(shù)傳遞

2011-09-08 11:35:18

2021-12-14 10:55:14

Python元素數(shù)據(jù)

2017-08-31 14:09:26

數(shù)據(jù)庫MySQLSQL優(yōu)化
點贊
收藏

51CTO技術(shù)棧公眾號