关于Java8 stream的相关使用及解析

Posted 冷月寒雪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Java8 stream的相关使用及解析相关的知识,希望对你有一定的参考价值。

文章目录


前言

蓦然回首,有好久不能够在休息日里去学习新知识、新技能,也好久没有把遇到的问题记录到博客中。往往只能够在工作日时,做好业务上的实现。今年求职过程中,竟然被问到了Java9,我甚至连Java8的函数式编程都没掌握明白。入职某药企,发现在其项目代码中大篇幅的使用函数式编程,左思右想,决定写记录一下Java8中stream的特性,增强自己的记忆力。

一、Stream是什么?

首先,Stream作为Java8的一大亮点,它与java.io包里的InputStream和OutputStream是完全的两个概念。Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作(bulk data operation)。
Stream API 借助于同样新出现的 Lambda 表达式,而且使用并发模式,极大的提高编程效率和程序可读性。
另外,Stream有几个特性:
1.Stream不改变数据源,会产生一个新的集合
2.Stream不存储数据,只是按照特定规则进行计算
3.Stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行

二、Stream使用

1.源码

从源码中不难看出,Stream提供的方法有很多,缩短时间,提取其中常用的几种方法进行说明。源码在java.util.stream.Stream 目录下,有时间的同学可以去研究研究。

1.collect

代码如下(示例):

    @Test
    public void test1()
        Integer[] numArr = 1, 2, 3, 4, 5;
        List<Integer> list = Stream.of(numArr).collect(Collectors.toList());
        log.info("list:",JSONObject.toJSONString(list));

    

将流转换为其他形式,接收一个Collect接口实现。
Collectors.toList()是Java 8 流的新类 java.util.stream.Collectors 实现了 java.util.stream.Collector 接口,同时又提供了大量的方法对流 ( stream ) 的元素执行 map and reduce 操作,或者统计操作。
Collectors.toList() 是将流中的所有元素导出到一个列表( List )中。

2.map / flatMap 映射转换

代码如下(示例):

  List<User> userList = new ArrayList<>();
            userList.add(new User(3, "张一鸣"));
            userList.add(new User(1, "zym"));
            userList.add(new User(2, "zhangyiming"));
            // 提取User的Name转成List集合
            List<String> nameList = userList.stream()
                    .map(User::getName).collect(Collectors.toList());
            System.out.println(nameList);   

该方法将list泛型对象中某一个属性提取,重新汇入一个list对象接收。输出为所有name。


3.filter过滤属性

代码如下(示例):

  List<Integer> numList = Arrays.asList(new Integer[] 1, 2, 3, 4, 5, 6);
        // 取出集合中的所有偶数
        numList = numList.stream()
                .filter(num -> num % 2 == 0).collect(Collectors.toList());
        System.out.println(numList ); 


在项目代码中也经常会使用到过滤属性,其目的是将当前list中,筛选出符合条件的参数,生成一个新Stream。

4.reduce 聚合

 		// 字符串拼接
        String[] arr = "a", "b", "c", "d";
        String content = Stream.of(arr).reduce("", String::concat);
        System.out.println(content);        //  输出 abcd

        // 求和, 需要一个起始参数值
        int sum = Stream.of(1, 2, 3, 4, 5, -2).reduce(0, Integer::sum);
        System.out.println(sum);            // 输出 13

        // 找最大值
        int maxNum = Stream.of(1, 3, 5, -2, 0).reduce(Integer::max).get();
        System.out.println(maxNum);        // 输出 5


BinaryOperator类表示对两个相同类型的操作数的运算,并产生与该操作数相同类型的结果,进入BinaryOperator源码查看,发现@FunctionalInterface,定义函数式接口,所以reduce的参数就一目了然了。

4.sorted 排序

在药企项目中发现一个比较奇怪的写法,查询库表把所有信息查询出来,通过Stream进行相关的条件过滤,利用sorted进行排序 返回至前台,我不太确定这样做是否能够提高性能,日后有时间出一篇性能比较。


基本DB层的数据拿过来后,利用Stream相关方法进行了过滤、分组、去重、排序。

代码如下(示例):

   Integer[] numArr = 2, 3, 1, 5, 0 ,8;
        List<Integer> numList = Stream.of(numArr)
                .sorted().collect(Collectors.toList());
        System.out.println(numList);        // 输出[0, 1, 2, 3, 5, 8]

        // 反向排序
        numList = Stream.of(numArr)
                .sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        System.out.println(numList);     

总结

以上就是关于Stream相关用法,时间关系,很多源码解读及运行过程未做详细说明,只提取了几种常用的方法给大家参考。同时,在使用性能上似乎存在了问题,关于Stream的性能问题我也阅读了很多文章,等日后有时间做一次性能比较后再进行补充。
不足之处,请批评指正

以上是关于关于Java8 stream的相关使用及解析的主要内容,如果未能解决你的问题,请参考以下文章

Java8用了这么久了,Stream 流用法及语法你都知道吗?

Java8新特性——Stream API的简单应用

Java8新特性——Stream API的简单应用

Java8 stream使用体验

Java8 stream使用体验

java8新特性Stream流操作详解及实战3