JDK8新特性-Map遍歷比較
阿新 • • 發佈:2018-12-11
菜鳥教程,有很多入門教程
1、案例
package com.cn.dl; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** * JDK8新特性,stream流,Map集合遍歷 * Created by Tiger on 2018/11/2. */ public class JDKDemo { private static int num = 2000000; public static void main(String[] args) { Map<String,String> map = new HashMap<String, String>(); int i= 0; while (i < num){ map.put("k_"+i,"v_"+i); i ++; } // TODO: 2018/11/2 測試1 // traverseMap(map); // TODO: 2018/11/2 測試2 // mapTest(map,"v_1"); // TODO: 2018/11/2 測試3 long startTime = System.currentTimeMillis(); Map<String,String> filterMap = filterMapValue(map,"v_1"); System.out.println(System.currentTimeMillis() - startTime); startTime = System.currentTimeMillis(); Map<String,String> filterMap1 = filterMapValue1(map,"v_1"); System.out.println(System.currentTimeMillis() - startTime); // traverseMap(filterMap1); startTime = System.currentTimeMillis(); Map<String,String> filterMap2 = filterMapValue2(map,"v_1"); System.out.println(System.currentTimeMillis() - startTime); // traverseMap(filterMap1); } /** * 遍歷map * */ public static void traverseMap(Map<String,String> map){ if (map == null || map.isEmpty()){ return; } //Lambda表示式,程式碼簡單易懂 map.forEach((k,v) ->{ System.out.println(k +","+ v); }); } /** * 統計map中包含某一類值的個數,如果是以前的話,這裡的程式碼應該會多好幾行 * contains:只要對應的String中包含,返回值就是true,否則false * */ private static long mapTest(Map<String,String> map,String contains){ long count = map.entrySet().stream().filter( entry -> (entry.getValue().contains(contains)) ).count(); System.out.println(count); return count; } /** * 過濾掉map中包含指定的value,然後返回過濾之後的map * */ private static Map<String,String> filterMapValue(Map<String,String> map,String contains){ if(map == null || map.isEmpty()){ return null; } return map.entrySet().stream().filter(entry -> ( ! entry.getValue().contains(contains) )).collect(Collectors.toMap( entry1 -> entry1.getKey(), entry2 -> entry2.getValue() )); } /** * 使用並行流過濾掉map中包含指定的value,然後返回過濾之後的map * todo 測試發現 parallelStream在資料大時速度明顯優於stream * todo 程式碼簡便,速度又快,為什麼不用呢。。。。。 * */ private static Map<String,String> filterMapValue1(Map<String,String> map,String contains){ if(map == null || map.isEmpty()){ return null; } return map.entrySet().parallelStream().filter(entry -> ! entry.getValue().contains(contains) ).collect(Collectors.toMap( entry1 -> entry1.getKey(), entry2 -> entry2.getValue() )); } /** * todo 測試發現,以前的老寫法比parallelStream快 * */ private static Map<String,String> filterMapValue2(Map<String,String> map,String contains){ if(map == null || map.isEmpty()){ return null; } Map<String,String> map1 = new HashMap<String, String>(); Set<Map.Entry<String,String>> entries = map.entrySet(); for(Map.Entry<String,String> entry : entries){ if(! entry.getValue().contains(contains)){ map1.put(entry.getKey(),entry.getValue()); } } return map1; } }
2、總結
當size=1000時
stream 耗時 >>>56
parallelStream 耗時 >>>5
for迴圈 耗時 >>>1
stream 耗時 >>>75
parallelStream 耗時 >>>9
for迴圈 耗時 >>>1
stream 耗時 >>>79
parallelStream 耗時 >>>8
for迴圈 耗時 >>>1
多執行幾次發現最開始的for迴圈耗時基本都是1毫秒
當size=100000時
stream 耗時 >>>117
parallelStream 耗時 >>>45
for迴圈 耗時 >>>28
stream 耗時 >>>91
parallelStream 耗時 >>>45
for迴圈 耗時 >>>26
stream 耗時 >>>92
parallelStream 耗時 >>>45
for迴圈 耗時 >>>22
當size=1000000時
stream 耗時 >>>1095 parallelStream 耗時 >>>358 for迴圈 耗時 >>>179
stream 耗時 >>>1058
parallelStream 耗時 >>>601
for迴圈 耗時 >>>213
stream 耗時 >>>1132
parallelStream 耗時 >>>303
for迴圈 耗時 >>>143
size再大一些,我們開始用的for迴圈遍歷map的速度永遠比JDK8-stream、parallelStream快很多,但是for迴圈程式碼稍微複雜,程式碼中使用很多臨時變數,佔用記憶體(其實可以忽略),JDK8 之後的stream,這種風格將要處理的元素集合看作一種流, 流在管道中傳輸, 並且可以在管道的節點上進行處理, 比如篩選, 排序,聚合等,程式碼簡潔乾淨,程式設計師的效率就變高了。