JDK11都发布了,你也该了解一些JDK1.8中提供的集合遍历操作方法喽

前言

今天分享一篇我的好基友的博客,可以说一路走来没少帮助过我!从上学期间一起打球开黑,到现在虽然相隔甚远,但依旧基情满满,也推荐大家去他的博客讨论一些技术人生,话不多说,这篇文章讨论的是关于JDK1.8新特性中提供的几个对集合遍历操作方式的讨论,有不同意见的小伙伴可以留言讨论。

案例

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;
    }
}

总结

当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,这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等,代码简洁干净,程序员的效率就变高了。

原文发布于微信公众号 - 程序猿杂货铺(zhoudl_l)

原文发表时间:2018-11-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券