• Java Stream流的使用


    1、为什么要使用流

        Stream是Java 8提供的新功能,是对集合(Collection)对象功能的增强,能对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数操作 (bulkdata operation)。 与Lambda 表达式结合,也可以提高编程效率、简洁性和程序可读性。
      个人使用流的最大感受是在遍历List时,代码更加简洁高效。比如之前我向集合中添加元素是这样的:
    以前的list循环遍历是:

    List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 6);
    for (Integer item : integerList){
        System.out.println(item);
    }
    
    • 1
    • 2
    • 3
    • 4

    现在的list遍历是:

    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
    list.stream().forEach(item -> System.out.println(item));
    
    • 1
    • 2

      当然流还有许多特性,如果熟悉流,能让你的代码更优雅,更有效率。下面就让我们来一起感受一下Stream的魅力。

    2、如何生成流

    生成流的方式主要有五种

    1、通过集合生成,应用中最常用的一种

    List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 6);
    Stream<Integer> stream = integerList.stream();
    
    • 1
    • 2

    2、通过数组生成

    int[] intArr = {1, 2, 3, 4, 5, 6};
    Stream<Integer> stream = (Stream) Arrays.stream(intArr);
    
    • 1
    • 2

    3、通过值生成

    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
    Stream stream = Stream.empty(); //空流
    
    • 1
    • 2

    4、通过文件生成

    // 每一行都是流的一个元素
    Stream<String> lines = Files.lines(Paths.get("data.txt"));
    lines.forEach(line-> System.out.println(item));
    
    • 1
    • 2
    • 3

    5、通过函数生成

    5.1 iterator

    Stream<Integer> stream = Stream.iterate(0, n -> n + 1).limit(6);
    
    • 1

    iterate方法接受两个参数,第一个为初始化值,第二个为进行的函数操作,因为iterator生成的流为无限流,通过limit方法对流进行了截断,只生成5个偶数。

    5.2 generator

    Stream<Double> stream = Stream.generate(Math::random).limit(6);
    
    • 1

    generate方法接受一个参数,方法参数类型为Supplier ,由它为流提供值。generate生成的流也是无限流,因此通过limit对流进行了截断。

    4、流的使用

    分为两种:中间操作和终端操作

    4.1 中间操作

    filter数据筛选

     例:通过filter筛选大于2小于5的数据

    List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 6);
    Stream<Integer> stream = integerList.stream().filter(i -> i>2 && i<5);
    
    • 1
    • 2

    distinct 数据去重

    limit 返回前n个流元素

    skip 跳过前n个流元素

    map 流映射

     所谓流映射就是将接受的元素映射成另外一个元素。
    例:将Stream中每个字符串的长度映射成一个list

    List<String> stringList = Arrays.asList("Hello word", "Lambdas is very useful", "In", "Action");
    List<Integer> list = stringList.stream()
        .map(item -> item.length())
        .collect(Collectors.toList());
    
    • 1
    • 2
    • 3
    • 4

    flatMap 流转换

    allMatch 匹配所有元素

    List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5, 6);
     if (dataList.stream().allMatch(i -> i > 2)) {
       System.out.println("所有元素都大于2");
     } else {
       System.out.println("不是所有元素都大于2");
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    anyMatch 匹配其中一个

     List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5, 6);
     if (dataList.stream().anyMatch(i -> i > 2)) {
       System.out.println("至少有一个元素大于2");
     } else {
       System.out.println("所有元素都小于等于2");
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    noneMatch 全部不匹配

    4.2 终端操作

    count 统计流中元素个数

    List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5, 6);
    
    long count = dataList.stream().count();
    
    • 1
    • 2
    • 3

    findFirst 查找第一个

    List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5);
    Optional<Integer> result = dataList.stream().filter(i -> i > 2).findFirst();
    System.out.println(result.orElse(-1));
    
    • 1
    • 2
    • 3

        Java中非常讨厌的一点就是NPE空指针异常,需要逐行检查是哪个对象为空,带来大量的不必要精力损耗,而在每个方法中加入非空检查,阅读性和维护性都比较差。
        Java 8中的Optional< T >是一个可以包含或不可以包含非空值的容器对象,在 Stream API中很多地方都使用到了Optional。
    更多内容可以查看这篇博客:如何更好地使用Java 8的Optional

    findAny 随机查找一个

    求和

    // 使用reduce函数
    List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5);
    int sum = dataList.stream()
        .reduce(0, Integer::sum);
    
    • 1
    • 2
    • 3
    • 4
    在这里插入代码片
    
    • 1

    获取最大最小值

    // 使用reduce函数
    List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5);
    Optional<Integer> max = dataList.stream()
        .reduce(Integer::max);
    System.out.println(max.orElse(-1));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    // 使用max()函数
    List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5);
    Optional<Integer> max = dataList.stream()
        .max(Integer::compareTo);
    System.out.println(max.orElse(-1));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    foreach 遍历

    collect 返回集合

    List<Integer> stringList = Arrays.asList(1, 2, 3, 4, 5);
    
    List<Integer> result = stringList.stream()
        .collect(toList());
    
    Set<Integer> intSet = stringList.stream()
        .collect(toSet());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

     利用Stream也可以拼接流元素,分组分区等,这里不过多介绍
    joining 拼接流中的元素
    groupingBy 分组
    partitioningBy 分区

  • 相关阅读:
    基于yolov5的手掌特效app(安卓)
    Jmeter(116)——写入xls登录案例实战
    开题报告:基于java摄影图片分享网站系统 毕业设计论文开题报告模板
    关于Unity 如何与Blazor Server结合
    【NOI模拟赛】最大生成树(Brouvka算法,并查集)
    一篇文章教你自动化测试如何解析excel文件?
    FFmpeg开发笔记(十二)Linux环境给FFmpeg集成libopus和libvpx
    基于Springboot实现高校社团管理系统
    没有前端如何测试后端跨域问题
    多种工具软件实现宿主机与Ubuntu虚拟机之间文件传输
  • 原文地址:https://blog.csdn.net/i_believe_you/article/details/127436172