文章目录

  • 前言
  • 一、Stream是什么?
  • 二、Stream使用
  • 1.源码
  • 1.collect
  • 2.map / flatMap 映射转换
  • 3.filter过滤属性
  • 4.reduce 聚合
  • 4.sorted 排序
  • 总结



前言

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

java stream 分析统计 java stream详解_java 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.源码

java stream 分析统计 java stream详解_java stream 分析统计_02

从源码中不难看出,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 );

java stream 分析统计 java stream详解_System_03


在项目代码中也经常会使用到过滤属性,其目的是将当前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

java stream 分析统计 java stream详解_后端_04


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

java stream 分析统计 java stream详解_List_05

4.sorted 排序

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

java stream 分析统计 java stream详解_System_06


java stream 分析统计 java stream详解_List_07


基本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的性能问题我也阅读了很多文章,等日后有时间做一次性能比较后再进行补充。

不足之处,请批评指正

java stream 分析统计 java stream详解_java stream 分析统计_08