1. 程式人生 > >JDK8新特性-Map遍歷比較

JDK8新特性-Map遍歷比較

菜鳥教程,有很多入門教程

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,這種風格將要處理的元素集合看作一種流, 流在管道中傳輸, 並且可以在管道的節點上進行處理, 比如篩選, 排序,聚合等,程式碼簡潔乾淨,程式設計師的效率就變高了。