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

HashMap的循環(huán)姿勢(shì)你真的使用對(duì)了嗎?

開(kāi)發(fā) 后端
hashMap 應(yīng)該是java程序員工作中用的比較多的一個(gè)鍵值對(duì)處理的數(shù)據(jù)的類型了。

[[342610]]

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

在for循環(huán)中使用entries實(shí)現(xiàn)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循環(huán)中遍歷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循環(huán)中遍歷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.     } 

以上就是常見(jiàn)的對(duì)于map的一些遍歷的方式,下面我們來(lái)寫個(gè)測(cè)試用例來(lái)看下這些遍歷方式,哪些是效率最好的。下面測(cè)試用例是基于JMH來(lái)測(cè)試的 首先引入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> 

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

  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:公眾號(hào):java金融 
  21.  * @Date:  
  22.  * @Description:微信搜一搜【java金融】回復(fù)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運(yùn)行之前進(jìn)行 
  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循環(huán)中使用entries實(shí)現(xiàn)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循環(huán)中遍歷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循環(huán)中遍歷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.  

運(yùn)行結(jié)果如下:「注:運(yùn)行環(huán)境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 

 

通過(guò)上述的圖我們可以發(fā)現(xiàn),數(shù)據(jù)量較小的時(shí)候forEachEntries和forEachIterator、以及l(fā)amada循環(huán)效率都差不多forEachStreamarallel的效率反而較低,只有當(dāng)數(shù)據(jù)量達(dá)到10000以上parallelStream的優(yōu)勢(shì)就體現(xiàn)出來(lái)了。所以平時(shí)選擇使用哪種循環(huán)方式的時(shí)候沒(méi)必要太糾結(jié)哪一種方式,其實(shí)每種方式之間的效率還是微乎其微的。選擇適合自己的就好。為什么parallelStream在數(shù)據(jù)量較小的時(shí)候效率反而不行?這個(gè)大家可以在下方留言哦。

總結(jié)

 

上面小實(shí)驗(yàn)只是在我機(jī)器上跑出來(lái)的結(jié)果,可能放到不同的機(jī)器運(yùn)行結(jié)果有不一樣哦,大家感興趣的同學(xué)可以把代碼貼到自己的機(jī)器上跑一跑,也許我這這個(gè)結(jié)論就不適用了。

本文轉(zhuǎn)載自微信公眾號(hào)「 java金融」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系 java金融公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: java金融
相關(guān)推薦

2022-05-09 07:27:50

ThreadLocaJava

2018-07-01 08:34:09

緩存數(shù)據(jù)服務(wù)

2022-03-11 14:59:21

JavaScript數(shù)組字符串

2017-11-09 13:56:46

數(shù)據(jù)庫(kù)MongoDB水平擴(kuò)展

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

隨機(jī)數(shù)偽隨機(jī)多線程

2019-03-08 16:30:44

MySQPHP數(shù)據(jù)庫(kù)

2020-08-04 08:37:23

Kafka分區(qū)數(shù)

2019-05-28 11:52:43

可視化圖表數(shù)據(jù)

2024-09-18 10:08:37

2020-06-29 08:32:21

高并發(fā)程序員流量

2018-03-19 10:39:28

Java序列化對(duì)象

2015-01-26 10:55:56

云服務(wù)器PowerEdge C

2022-01-12 18:35:54

MongoDB數(shù)據(jù)查詢

2022-04-07 08:20:22

typeinterface前端

2024-01-25 10:14:09

HashSetHashMapJava

2018-01-25 16:49:08

開(kāi)源容器云編排工具
點(diǎn)贊
收藏

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