成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

HashMap的循環姿勢你真的使用對了嗎?

開發 后端
hashMap 應該是java程序員工作中用的比較多的一個鍵值對處理的數據的類型了。

[[342610]]

hashMap 應該是java程序員工作中用的比較多的一個鍵值對處理的數據的類型了。hashMap 有常見的六七種遍歷的方式。這么多的選擇,大家平時都是使用哪一種來遍歷數據列?歡迎大家在下方留言哦。說實話這么多種方式,想記也不記不住,也不想浪費時間來記這玩意,所以本人在JDK1.8以前基本上都是用Map.Entry的方式來遍歷,1.8及以后就習慣性用forEach了,不過這個不能有continue或者break操作這個有時候還是挺不方便的,其他幾種基本上沒怎么用過,也沒太研究這幾種方式,哪種性能是比較好的。反正就是挑自己熟悉的方式。好了話不多說,我們還是直入今天的主題。先來看看每種遍歷的方式:

在for循環中使用entries實現Map的遍歷

  1. public static void forEachEntries() { 
  2.         for (Map.Entry<String, String> entry : map.entrySet()) { 
  3.             String mapKey = entry.getKey(); 
  4.             String mapValue = entry.getValue(); 
  5.         } 
  6.     } 

在for循環中遍歷key

  1. public static void forEachKey() { 
  2.         for (String key : map.keySet()) { 
  3.             String mapKey = key
  4.             String mapValue = map.get(mapKey); 
  5.         } 
  6.     } 

在for循環中遍歷value

  1. public static void forEachValues() { 
  2.         for (String key : map.values()) { 
  3.             String val = key
  4.         } 
  5.     } 

Iterator遍歷

  1. public static void forEachIterator() { 
  2.         Iterator<Entry<String, String>> entries = map.entrySet().iterator(); 
  3.         while (entries.hasNext()) { 
  4.             Entry<String, String> entry = entries.next(); 
  5.             String key = entry.getKey(); 
  6.             String value = entry.getValue(); 
  7.         } 
  8.     } 

forEach jdk1.8遍歷

  1. public static void forEach() { 
  2.         map.forEach((key, val) -> { 
  3.             String key1 = key
  4.             String value = val; 
  5.         }); 
  6.     } 

Stream jdk1.8遍歷

  1. map.entrySet().stream().forEach((entry) -> { 
  2.             String key = entry.getKey(); 
  3.             String value = entry.getValue(); 
  4.         }); 

Streamparallel jdk1.8遍歷

  1. public static void forEachStreamparallel() { 
  2.         map.entrySet().parallelStream().forEach((entry) -> { 
  3.             String key = entry.getKey(); 
  4.             String value = entry.getValue(); 
  5.         }); 
  6.     } 

以上就是常見的對于map的一些遍歷的方式,下面我們來寫個測試用例來看下這些遍歷方式,哪些是效率最好的。下面測試用例是基于JMH來測試的 首先引入pom

  1. <dependency> 
  2.             <groupId>org.openjdk.jmh</groupId> 
  3.             <artifactId>jmh-core</artifactId> 
  4.             <version>1.23</version> 
  5.         </dependency> 
  6.         <dependency> 
  7.             <groupId>org.openjdk.jmh</groupId> 
  8.             <artifactId>jmh-generator-annprocess</artifactId> 
  9.             <version>1.23</version> 
  10.             <scope>provided</scope> 
  11.         </dependency> 

關于jmh測試如可能會影響結果的一些因素這里就不詳細介紹了,可以參考文末的第一個鏈接寫的非常詳細。以及測試用例為什么要這么寫(都是為了消除JIT對測試代碼的影響)這是參照官網的鏈接:編寫測試代碼如下:

  1. package com.workit.autoconfigure.autoconfigure.controller; 
  2.  
  3.  
  4. import org.openjdk.jmh.annotations.*; 
  5. import org.openjdk.jmh.infra.Blackhole; 
  6. import org.openjdk.jmh.results.format.ResultFormatType; 
  7. import org.openjdk.jmh.runner.Runner; 
  8. import org.openjdk.jmh.runner.RunnerException; 
  9. import org.openjdk.jmh.runner.options.Options; 
  10. import org.openjdk.jmh.runner.options.OptionsBuilder; 
  11.  
  12. import java.util.HashMap; 
  13. import java.util.Iterator; 
  14. import java.util.Map; 
  15. import java.util.Map.Entry; 
  16. import java.util.UUID; 
  17. import java.util.concurrent.TimeUnit; 
  18.  
  19. /** 
  20.  * @author:公眾號:java金融 
  21.  * @Date:  
  22.  * @Description:微信搜一搜【java金融】回復666 
  23.  */ 
  24.  
  25. @State(Scope.Thread) 
  26. @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) 
  27. @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) 
  28. @Fork(1) 
  29. @BenchmarkMode(Mode.AverageTime) 
  30. @OutputTimeUnit(TimeUnit.NANOSECONDS) 
  31. public class InstructionsBenchmark { 
  32.     public static void main(String[] args) throws RunnerException { 
  33.         Options opt = new OptionsBuilder().include(InstructionsBenchmark.class.getSimpleName()).result("result.json").resultFormat(ResultFormatType.JSON).build(); 
  34.         new Runner(opt).run(); 
  35.     } 
  36.  
  37.     static final int BASE = 42; 
  38.  
  39.     static int add(int key,int val) { 
  40.       return  BASE + key +val; 
  41.     } 
  42.     @Param({"1""10""100""1000","10000","100000"}) 
  43.     int size
  44.     private static Map<IntegerInteger>  map; 
  45.  
  46.     // 初始化方法,在全部Benchmark運行之前進行 
  47.     @Setup(Level.Trial) 
  48.     public void init() { 
  49.         map = new HashMap<>(size); 
  50.         for (int i = 0; i < size; i++) { 
  51.             map.put(i, i); 
  52.         } 
  53.     } 
  54.  
  55.  
  56.     /** 
  57.      * 在for循環中使用entries實現Map的遍歷: 
  58.      */ 
  59.     @Benchmark 
  60.     public static void forEachEntries(Blackhole blackhole) { 
  61.         for (Map.Entry<IntegerInteger> entry : map.entrySet()) { 
  62.             Integer mapKey = entry.getKey(); 
  63.             Integer mapValue = entry.getValue(); 
  64.             blackhole.consume(add(mapKey,mapValue)); 
  65.         } 
  66.     } 
  67.  
  68.     /** 
  69.      * 在for循環中遍歷key 
  70.      */ 
  71.     @Benchmark 
  72.     public static StringBuffer forEachKey(Blackhole blackhole) { 
  73.         StringBuffer stringBuffer = new StringBuffer(); 
  74.         for (Integer key : map.keySet()) { 
  75.           //  Integer mapValue = map.get(key); 
  76.             blackhole.consume(add(key,key)); 
  77.         } 
  78.         return stringBuffer; 
  79.     } 
  80.  
  81.     /** 
  82.      * 在for循環中遍歷value 
  83.      */ 
  84.     @Benchmark 
  85.     public static void forEachValues(Blackhole blackhole) { 
  86.         for (Integer key : map.values()) { 
  87.             blackhole.consume(add(key,key)); 
  88.         } 
  89.     } 
  90.  
  91.     /** 
  92.      * Iterator遍歷; 
  93.      */ 
  94.     @Benchmark 
  95.     public static void forEachIterator(Blackhole blackhole) { 
  96.         Iterator<Entry<IntegerInteger>> entries = map.entrySet().iterator(); 
  97.         while (entries.hasNext()) { 
  98.             Entry<IntegerInteger> entry = entries.next(); 
  99.             Integer key = entry.getKey(); 
  100.             Integer value = entry.getValue(); 
  101.             blackhole.consume(add(key,value)); 
  102.         } 
  103.     } 
  104.  
  105.     /** 
  106.      * forEach jdk1.8遍歷 
  107.      */ 
  108.     @Benchmark 
  109.     public static void forEachLamada(Blackhole blackhole) { 
  110.         map.forEach((key, value) -> { 
  111.             blackhole.consume(add(key,value)); 
  112.         }); 
  113.  
  114.     } 
  115.  
  116.     /** 
  117.      * forEach jdk1.8遍歷 
  118.      */ 
  119.     @Benchmark 
  120.     public static void forEachStream(Blackhole blackhole) { 
  121.         map.entrySet().stream().forEach((entry) -> { 
  122.             Integer key = entry.getKey(); 
  123.             Integer value = entry.getValue(); 
  124.             blackhole.consume(add(key,value)); 
  125.  
  126.         }); 
  127.     } 
  128.  
  129.     @Benchmark 
  130.     public static void forEachStreamparallel(Blackhole blackhole) { 
  131.         map.entrySet().parallelStream().forEach((entry) -> { 
  132.             Integer key = entry.getKey(); 
  133.             Integer value = entry.getValue(); 
  134.             blackhole.consume(add(key,value)); 
  135.  
  136.         }); 
  137.     } 
  138.  

運行結果如下:「注:運行環境idea 2019.3,jdk1.8,windows7 64位。」

  1. Benchmark                                    (size)  Mode  Cnt        Score        Error  Units 
  2. InstructionsBenchmark.forEachEntries              1  avgt    5       10.021 ±      0.224  ns/op 
  3. InstructionsBenchmark.forEachEntries             10  avgt    5       71.709 ±      2.537  ns/op 
  4. InstructionsBenchmark.forEachEntries            100  avgt    5      738.873 ±     12.132  ns/op 
  5. InstructionsBenchmark.forEachEntries           1000  avgt    5     7804.431 ±    136.635  ns/op 
  6. InstructionsBenchmark.forEachEntries          10000  avgt    5    88540.345 ±  14915.682  ns/op 
  7. InstructionsBenchmark.forEachEntries         100000  avgt    5  1083347.001 ± 136865.960  ns/op 
  8. InstructionsBenchmark.forEachIterator             1  avgt    5       10.675 ±      2.532  ns/op 
  9. InstructionsBenchmark.forEachIterator            10  avgt    5       73.934 ±      4.517  ns/op 
  10. InstructionsBenchmark.forEachIterator           100  avgt    5      775.847 ±    198.806  ns/op 
  11. InstructionsBenchmark.forEachIterator          1000  avgt    5     8905.041 ±   1294.618  ns/op 
  12. InstructionsBenchmark.forEachIterator         10000  avgt    5    98686.478 ±  10944.570  ns/op 
  13. InstructionsBenchmark.forEachIterator        100000  avgt    5  1045309.216 ±  36957.608  ns/op 
  14. InstructionsBenchmark.forEachKey                  1  avgt    5       18.478 ±      1.344  ns/op 
  15. InstructionsBenchmark.forEachKey                 10  avgt    5       76.398 ±     12.179  ns/op 
  16. InstructionsBenchmark.forEachKey                100  avgt    5      768.507 ±     23.892  ns/op 
  17. InstructionsBenchmark.forEachKey               1000  avgt    5    11117.896 ±   1665.021  ns/op 
  18. InstructionsBenchmark.forEachKey              10000  avgt    5    84871.880 ±  12056.592  ns/op 
  19. InstructionsBenchmark.forEachKey             100000  avgt    5  1114948.566 ±  65582.709  ns/op 
  20. InstructionsBenchmark.forEachLamada               1  avgt    5        9.444 ±      0.607  ns/op 
  21. InstructionsBenchmark.forEachLamada              10  avgt    5       76.125 ±      5.640  ns/op 
  22. InstructionsBenchmark.forEachLamada             100  avgt    5      861.601 ±     98.045  ns/op 
  23. InstructionsBenchmark.forEachLamada            1000  avgt    5     7769.714 ±   1663.914  ns/op 
  24. InstructionsBenchmark.forEachLamada           10000  avgt    5    73250.238 ±   6032.161  ns/op 
  25. InstructionsBenchmark.forEachLamada          100000  avgt    5   836781.987 ±  72125.745  ns/op 
  26. InstructionsBenchmark.forEachStream               1  avgt    5       29.113 ±      3.275  ns/op 
  27. InstructionsBenchmark.forEachStream              10  avgt    5      117.951 ±     13.755  ns/op 
  28. InstructionsBenchmark.forEachStream             100  avgt    5     1064.767 ±     66.869  ns/op 
  29. InstructionsBenchmark.forEachStream            1000  avgt    5     9969.549 ±    342.483  ns/op 
  30. InstructionsBenchmark.forEachStream           10000  avgt    5    93154.061 ±   7638.122  ns/op 
  31. InstructionsBenchmark.forEachStream          100000  avgt    5  1113961.590 ± 218662.668  ns/op 
  32. InstructionsBenchmark.forEachStreamparallel       1  avgt    5       65.466 ±      5.519  ns/op 
  33. InstructionsBenchmark.forEachStreamparallel      10  avgt    5     2298.999 ±    721.455  ns/op 
  34. InstructionsBenchmark.forEachStreamparallel     100  avgt    5     8270.759 ±   1801.082  ns/op 
  35. InstructionsBenchmark.forEachStreamparallel    1000  avgt    5    16049.564 ±   1972.856  ns/op 
  36. InstructionsBenchmark.forEachStreamparallel   10000  avgt    5    69230.849 ±  12169.260  ns/op 
  37. InstructionsBenchmark.forEachStreamparallel  100000  avgt    5   638129.559 ±  14885.962  ns/op 
  38. InstructionsBenchmark.forEachValues               1  avgt    5        9.743 ±      2.770  ns/op 
  39. InstructionsBenchmark.forEachValues              10  avgt    5       70.761 ±     16.574  ns/op 
  40. InstructionsBenchmark.forEachValues             100  avgt    5      745.069 ±    329.548  ns/op 
  41. InstructionsBenchmark.forEachValues            1000  avgt    5     7772.584 ±   1702.295  ns/op 
  42. InstructionsBenchmark.forEachValues           10000  avgt    5    74063.468 ±  23752.678  ns/op 
  43. InstructionsBenchmark.forEachValues          100000  avgt    5   994057.370 ± 279310.867  ns/op 

 

通過上述的圖我們可以發現,數據量較小的時候forEachEntries和forEachIterator、以及lamada循環效率都差不多forEachStreamarallel的效率反而較低,只有當數據量達到10000以上parallelStream的優勢就體現出來了。所以平時選擇使用哪種循環方式的時候沒必要太糾結哪一種方式,其實每種方式之間的效率還是微乎其微的。選擇適合自己的就好。為什么parallelStream在數據量較小的時候效率反而不行?這個大家可以在下方留言哦。

總結

 

上面小實驗只是在我機器上跑出來的結果,可能放到不同的機器運行結果有不一樣哦,大家感興趣的同學可以把代碼貼到自己的機器上跑一跑,也許我這這個結論就不適用了。

本文轉載自微信公眾號「 java金融」,可以通過以下二維碼關注。轉載本文請聯系 java金融公眾號。

 

責任編輯:武曉燕 來源: java金融
相關推薦

2022-05-09 07:27:50

ThreadLocaJava

2018-07-01 08:34:09

緩存數據服務

2022-03-11 14:59:21

JavaScript數組字符串

2017-11-09 13:56:46

數據庫MongoDB水平擴展

2013-07-15 16:55:45

2024-12-17 15:00:00

字符串Java

2021-03-16 06:47:47

Python

2019-12-26 14:07:19

隨機數偽隨機多線程

2019-03-08 16:30:44

MySQPHP數據庫

2020-08-04 08:37:23

Kafka分區數

2024-09-18 10:08:37

2019-05-28 11:52:43

可視化圖表數據

2020-06-29 08:32:21

高并發程序員流量

2018-03-19 10:39:28

Java序列化對象

2015-01-26 10:55:56

云服務器PowerEdge C

2022-01-12 18:35:54

MongoDB數據查詢

2025-06-25 02:00:00

2022-04-07 08:20:22

typeinterface前端

2018-07-04 06:26:00

無線路由器網絡WiFi
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 97精品国产97久久久久久免费 | 亚洲综合色视频在线观看 | 91精品一区二区三区久久久久 | 日韩一区二区三区视频 | 97精品国产97久久久久久免费 | 日韩中文字幕 | 免费观看一级黄色录像 | 日韩一区二区三区av | 日韩午夜电影在线观看 | 丝袜美腿一区 | 久久免费电影 | 久草在线青青草 | 日本精品999| 欧美日韩亚洲国产综合 | 中文字幕成人av | 欧美精品久久 | 久久亚洲天堂 | 国产亚洲一区二区三区在线观看 | 夜夜爽99久久国产综合精品女不卡 | 最近最新中文字幕 | 国产亚洲欧美在线视频 | 亚洲欧美激情精品一区二区 | 久久精品国产免费 | 亚洲美女网站 | 午夜精品久久久久久久久久久久久 | 精品久久久久久久 | 欧美一区二区二区 | 亚洲成人高清 | 99精品欧美一区二区蜜桃免费 | 18av在线播放| 天天操夜夜艹 | 日韩av最新网址 | 亚洲精品一区二区另类图片 | 男人天堂网址 | 国产成人精品亚洲日本在线观看 | 国产精品国产三级国产aⅴ入口 | 精品乱码一区二区 | 亚洲视频中文字幕 | 久久久久久久久中文字幕 | 欧美日韩亚洲国产综合 | 国产特级毛片aaaaaa喷潮 |