当前位置:   article > 正文

Java 8 Stream 流详解_java 集合stream.stream需要close么

java 集合stream.stream需要close么

1、stream 简介

Java 8 中有两个重要的改变,一个是 Lambda 表达式,另外一个是 Stream API(java.util.stream.*)

Stream 流的特点:

  • stream 流不会改变数据源,一般会产生一个新的集合来存储按照我们特定规则计算后的结果
  • stream 会延迟执行,在调用终端操作时中间操作才会执行

1.1 stream 在 java 中的定义:

// 支持顺序和并行聚合操作的元素序列
A sequence of elements supporting sequential and parallel aggregate operations. 

// 以下示例演示了使用Stream和IntStream的聚合操作:    
The following example illustrates an aggregate operation using Stream and IntStream:

// 示例:
int sum = widgets.stream()
    .filter(w -> w.getColor() == RED)
    .mapToInt(w -> w.getWeight())
    .sum();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定希望对集合进行的操作,可以执行复杂的查找、过滤和映射数据等操作

1.2 Stream 流接口继承关系

在这里插入图片描述

最上面的 AutoCloseable 这个接口只有一个方法

void close() throws Exception;
  • 1

这个方法关闭调用对象,释放可能占用的所有资源。在带资源的try语句的末尾,会自动调用该方法,不用显式调用close()方法

BaseStream 接口:

BaseStream 这个接口是 Stream 流的基类,这个类定义了 Stream 流的主要行为

public interface BaseStream<T, S extends BaseStream<T, S>> extends AutoCloseable {
    //获得流的迭代器(终端操作)
    Iterator<T> iterator();
    // 获取流的并行迭代器(终端操作)
    Spliterator<T> spliterator();
    // 并行流返回true,顺序流返回false
    boolean isParallel();
    // 返回一个顺序流(中间操作)
    S sequential();
    // 返回一个并行流(中间操作)
    S parallel();
    // 返回一个无序流(中间操作)
    S unordered();
    // 关闭流时调用,返回一个新流
    S onClose(Runnable closeHandler);
    // 父类 AutoCloseable 关闭流的方法
    @Override
    void close();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

1.3 中间操作和终端操作

Stream 流上的操作可以分为 中间操作(Intermediate)和终端操作(Terminal)

中间操作

  • 中间操作会产生一个新的 Stream 流,可以多个中间操作叠加
  • 中间操作不是立即发生的,而是延迟发生的,中间操作创建的新流执行完终端操作后才会发生

终端操作

  • 终端操作返回我们最终需要的数据,只能有一个终止操作

2、Stream 流使用

2.1 Stream 流创建

  1. 通过 Collection 接口的 stream() 或者 parallelStream() 方法创建

    List<String> list = Arrays.asList("1", "2", "3");
    // 创建普通流,主线程按顺序对流进行操作
    Stream<String> stream1 = list.stream();
    // 创建并行流,多线程并行对流进行操作
    Stream<String> stream2 = list.parallelStream();
    // 使用 parallel() 将顺序流转换为并行流
    Stream<String> stream8 = stream1.parallel();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  2. 使用 Stream 的静态方法
    在这里插入图片描述

    Stream<String> stream3 = Stream.empty();
    Stream<String> stream4 = Stream.of("1", "2", "3");
    // 将两个流连接起来
    Stream<String> stream5 = Stream.concat(stream1, stream2); 
    ... ...
    Stream.generate();
    Stream.iterate();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  3. 使用 Arraysstream() 方法

    int[] arr = {1, 2, 3};
    IntStream stream = Arrays.stream(arr);
    
    • 1
    • 2

2.2 Stream 流中间操作(Intermediate)

  1. filter(Predicate):筛选,结果为 false 的元素会过滤掉

    List<String> list = Arrays.asList("1", "2", "3", "4", "5");
    // 筛选等于 "3" 的第一个元素
    Optional<String> first = list.stream().filter(x -> x == "3").findFirst();
    System.out.println(first.get()); // 输出结果:3
    
    • 1
    • 2
    • 3
    • 4
  2. map:映射

    1. map(fun):转换元素的值,一个流的元素按函数处理后映射为新的元素

      List<String> list = Arrays.asList("he", "ha", "hia", "hua");
      // 所有元素大写
      list.stream().map(x -> x.toUpperCase()).forEach(System.out::println);
      // 输出结果:HE HA HIA HUA
      
      • 1
      • 2
      • 3
      • 4
    2. flatMap(fun):流中的每个值都换成另外一个流,再将所有的流连接成一个

      List<String> list = Arrays.asList("h-e", "h-a", "h-i-a", "h-u-a");
      List<String> collect = list.stream().flatMap(x -> Arrays.stream(x.split("-"))).collect(Collectors.toList());
      System.out.println(collect);
      // 输出结果:[h, e, h, a, h, i, a, h, u, a]
      
      • 1
      • 2
      • 3
      • 4
  3. limit(n):截取,保留 n 个元素

    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 2, 3, 6);
    // 保留 3 个元素
    list.stream().limit(3).forEach(System.out::println);
    // 输出结果:1 2 3
    
    • 1
    • 2
    • 3
    • 4
  4. skip(n):跳过,跳过 n 个元素

    List<String> list = Arrays.asList("1", "2", "3", "4", "5", "3");
    // 跳过 3 个元素筛选等于 "3" 的第一个元素
    Optional<String> first = list.stream().skip(3).filter(x -> x == "3").findFirst();
    System.out.println(first); // 输出结果:3
    
    • 1
    • 2
    • 3
    • 4
  5. distinct():去重,去除重复元素

    List<String> list = Arrays.asList("1", "2", "3", "4", "5", "3");
    // 去重遍历
    list.stream().distinct().forEach(System.out::println);
    
    • 1
    • 2
    • 3
  6. sorted:排序自然排序

    List<Integer> list = Arrays.asList(5, 2, 3, 4, 5, 2, 3, 6);
    // 去重并排序
    List<Integer> collect = list.stream().distinct().sorted().collect(Collectors.toList());
    System.out.println(collect);
    
    • 1
    • 2
    • 3
    • 4

2.3 Stream 流终止操作(Terminal)

  • foreach:遍历

    List<String> list = Arrays.asList("he", "ha", "hia", "hua");
    // 遍历输出
    list.stream().forEach(x -> {
        System.out.println(x);
    });
    // 结果:he ha hia hua
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • find

    List<String> list = Arrays.asList("1", "2", "3", "4", "5");
    // 筛选等于 "3" 的第一个元素
    Optional<String> first = list.stream().filter(x -> x == "3").findFirst();
    System.out.println(first.get()); // 输出结果:3
    
    • 1
    • 2
    • 3
    • 4
  • count()

    List<String> list = Arrays.asList("1", "2", "3", "4", "5", "3");
    // 等于 "3" 的元素的数量
    long count = list.stream().filter(x -> x == "3").count();
    System.out.println(count); // 输出结果:2
    
    • 1
    • 2
    • 3
    • 4
  • max(Comparator)

    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 2, 3, 6);
    // 集合中最大的元素
    Optional<Integer> max = list.stream().max(Integer::compareTo);
    System.out.println(max.get()); // 结果为:6
    
    • 1
    • 2
    • 3
    • 4
  • min(Comparator)

    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 2, 3, 6);
    // 集合中最小的元素
    Optional<Integer> max = list.stream().min(Integer::compareTo);
    System.out.println(max.get()); // 结果为:1
    
    • 1
    • 2
    • 3
    • 4
  • reduce:缩减,可以把一个 stream 流缩减成一个值,实现求和、求最值等操作

    • 求和

      // 对集合中的元素求和
      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
      // 第一种求和方式
      Integer sum = list.stream().reduce((x, y) -> x + y).get();
      // 第二种求和方式
      Integer sum2 = list.stream().reduce(Integer::sum).get();
      // 第三种求和方式(集合中的元素求和再加 1)
      Integer sum3 = list.stream().reduce(3, Integer::sum);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 求最值

      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
      // 求最大值 1
      Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);
      // 求最大值 2
      Integer sum2 = list.stream().reduce(Integer::max).get();
      
      • 1
      • 2
      • 3
      • 4
      • 5
  • collect:收集操作,把 stream 流收集起来,成为一个新的值或者集合

    • toListtoSettoMap

      List<String> list = Arrays.asList("he", "ha", "hia", "hua", null);
      // toList
      List<String> collect = list.stream().filter(Objects::nonNull).collect(Collectors.toList());
      System.out.println(collect); //[he, ha, hia, hua]
      // toSet
      Set<String> set = list.stream().filter(Objects::nonNull).collect(Collectors.toSet());
      System.out.println(set); // [hia, hua, ha, he]
      // toMap
      Map<String, String> map = list.stream().filter(Objects::nonNull).collect(Collectors.toMap(x -> x, x -> x));
      System.out.println(map); // {hia=hia, hua=hua, ha=ha, he=he}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 平均值 averagingDoubleaveragingLongaveragingInt

      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
      // 求平均值
      Double average = list.stream().collect(Collectors.averagingDouble(Integer::intValue));
      System.out.println(average);
      
      • 1
      • 2
      • 3
      • 4
    • 计数 count

      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
      // 求总数
      Long count = list.stream().collect(Collectors.counting());
      System.out.println(count);
      
      • 1
      • 2
      • 3
      • 4
    • 最值 maxByminBy

      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
      // 求最高值
      Integer max = list.stream().collect(Collectors.maxBy(Integer::compare)).get();
      System.out.println(max);
      
      • 1
      • 2
      • 3
      • 4
    • 求和 summingIntsummingLongsummingDubbo

      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
      // 求和
      Integer sum = list.stream().collect(Collectors.summingInt(Integer::intValue));
      System.out.println(sum);
      
      • 1
      • 2
      • 3
      • 4
    • 统计所有 summarizingIntsummarizingLongsummarizingDouble

      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
      // 统计所有信息
      DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(Integer::intValue));
      System.out.println(collect);
      
      • 1
      • 2
      • 3
      • 4
    • 分组 partitioningBy(按条件分区)groupingBy(可按条件多次分组)

      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 23, 6, -19, 32, 5, 12, 8);
      // 按照是否大于 10 进行分组
      Map<Boolean, List<Integer>> collect = list.stream().collect(Collectors.partitioningBy(x -> x > 10));
      System.out.println(collect); 
      // 返回结果:{false=[1, 2, 3, 4, 5, 6, 6, -19, 5, 8], true=[23, 32, 12]}
      // 按照是否大于 10 进行分组后,再按照是否大于 15 进行分组
      Map<Object, Map<Object, List<Integer>>> collect2 = list.stream().collect(Collectors.groupingBy(x -> x > 10, Collectors.groupingBy(x -> x > 15)));
      System.out.println(collect2); 
      // 返回结果:{false={false=[1, 2, 3, 4, 5, 6, 6, -19, 5, 8]}, true={false=[12], true=[23, 32]}}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 连接 joining 流中的元素用一个连接符进行拼接

      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 23, 6, -19, 32, 5, 12, 8);
      // 去重并用 ~ 拼接
      String collect = list.stream().distinct().map(x -> x.toString()).collect(Collectors.joining("~"));
      
      • 1
      • 2
      • 3
    • 排序 sorted(Comparator):自定义排序

      List<Integer> list = Arrays.asList(5, 2, 3, 4, 5, 2, 3, 6);
      // 去重并排序
      List<Integer> collect = list.stream().distinct().sorted().collect(Collectors.toList());
      System.out.println(collect);
      // 输出结果:[-19, 1, 2, 3, 4, 5, 6, 8, 12, 23, 32]
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 合并 Stream.concat(stream1, stream2)

      List<Integer> list1 = Arrays.asList(5, 2, 3, 4, 5, 2, 3, 6);
      List<Integer> list2 = Arrays.asList(1, 6, 23, -19, 32, 5, 12, 8);
      // 去重合并两个流输出
      Stream.concat(list1.stream(), list2.stream()).distinct().sorted(Integer::compareTo).forEach(System.out::print);
      // 输出结果:-19 1 2 3 4 5 6 8 12 23 32
      
      • 1
      • 2
      • 3
      • 4
      • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/367347
推荐阅读
相关标签
  

闽ICP备14008679号