专栏首页程序猿杂货铺JDK11都发布了,你也该了解一些JDK1.8中提供的集合遍历操作方法喽

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),作者:燕少江湖

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

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

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 你不知道的 Java 注解那些事!

    注解对于开发人员来讲既熟悉又陌生,熟悉是因为只要你是做开发,都会用到注解(常见的 @Override),陌生是因为即使不使用注解也照常能够进行开发,注解不是必须...

    周三不加班
  • 【分布式架构基石】网络通信协议

    协议,网络协议的简称,网络协议是通信计算机双方必须共同遵从的一组约定。如怎么样建立连接、怎么样互相识别等。只有遵守这个约定,计算机之间才能相互通信交流。它的三要...

    周三不加班
  • 一次Java内存泄漏调试的有趣经历

    人人都会犯错,但一些错误是如此的荒谬,我想不通怎么会有人犯这种错误。更没想到的是,这种事竟发生在了我们身上。当然,这种东西只有事后才能发现真相。接下来,我将讲述...

    周三不加班
  • 高维数据 | R语言数据可视化之日历图

    日历图,在环境与生态指标的动态监测中应用普遍,特别适用于显示不同时间段的指标情况。比如污染物中重金属含量、空气中PM2.5变化情况。在金融行业中检测股票收...

    黑妹的小屋
  • 统计一个字符串中每一个字符出现的次数

    WindCoder
  • PHP PDO数据库操作预处理与注意事项

    PDO(PHP Database Object)扩展为PHP访问数据库定义了一个轻量级的、一致性的接口,它提供了一个数据访问抽象层,这样,无论使用什么数据库,都...

    砸漏
  • 使用腾讯云无服务器云函数(SCF)分析天气数据

    无服务器云函数(SCF)是腾讯云提供的Serverless执行环境,也是国内首款FaaS(Function as a Service,函数即服务) 产品。其核心...

    李想
  • phalcon-入门篇6(控制器)

    #phalcon-入门篇6(控制器)# ? 本教程基于phalcon2.0.9版本 ##前言## 先在这里感谢各位phalcon技术爱好者,我们提供这样一个优秀...

    喵了个咪233
  • StringBuffer类

    区别:StringBuffer类可以改变字符串中的内容,而String类则无法改变被初始化过的字符串内容(改变的只是String字符串的引用位置)

    Mirror王宇阳
  • 2017-10271weblogic漏洞exp测试及补丁测试

    逆向小白

扫码关注云+社区

领取腾讯云代金券