Stream流

Stream流

介绍

Stream是Java 8中引入的新特性,它是一个用于描述对集合、数组等数据进行处理的API。它可以极大的简化集合类(包括数组)的处理操作,并且提供了强大的功能,比如过滤、转换、排序、聚合等。

原则

  • 声明式:Stream的操作不涉及底层数据存储和实现细节,更侧重于描述要执行的操作。
  • 可组合:可以将多个操作连接起来,形成一个链式操作(在终止操作遍历时,根据先后顺序执行多个操作)。
  • 延迟执行:Stream的中间操作只有在终止操作(如forEach)时才会执行。

原理

  1. 创建一个Stream对象,可以通过集合、数组等方式来创建。
  2. 中间操作,对Stream对象进行一系列的操作,比如过滤、映射、排序等操作,这些操作可以串联起来形成一个Pipeline(管道)。
  3. 终端操作,最后执行终止操作,触发流的执行,得到结果。

特点

  1. Stream不会改变源数据,所有的操作都是基于数据源的一个新的视图(理解:相当于对一个新的集合继续操作)
  2. Stream的操作可以进行优化,如并行执行等,提高了数据处理的效率

注意事项

  1. Stream的操作是延迟执行的,需要注意终止操作的使用时机,否则可能出现数据不完整的情况。
  2. Stream的操作不会改变源数据,需要注意收集操作的使用时机,否则可能造成数据的浪费。
  3. Stream操作可以链式调用,但终端操作只能有一个。
  4. Stream可以并行处理,提高处理效率。但需要注意线程安全问题。

Stream创建方式(三种)

Stream<T> stream = collection.stream(); // 通过集合创建Stream
Stream<T> stream = Arrays.stream(arr); // 通过数组创建Stream
Stream<T> stream = Stream.of(t1, t2, t3); // 直接创建Stream

常见API

常用API方法

在JDK中,提供了非常丰富的API方法,主要分为以下两类:

延迟方法(中间操作)

返回值类型仍然为Stream接口自身类型的方法,因此支持链式调用。如:

  • 筛选与切片
    • filter:过滤出符合条件的元素
    • limit:截断流,使其元素不超过给定数量
    • skip:跳过前n个元素,返回剩下的元素
    • distinct:去重,根据元素的hashCode()和equals()方法实现
  • 映射
    • map:将元素按照指定的方式转换
    • mapToDouble:将元素转换为double类型
    • mapToInt:将元素转换为int类型
    • mapToLong:将元素转换为long类型
    • flatMap:将元素按照指定的方式转换,返回一个流
  • 排序
    • sorted:自然排序
    • sorted(Comparator comparator):自定义排序
  • 组合:
    • concat:连接两个流

终结方法:返回值类型不再是Stream接口自身类型的方法。

返回元素的返回类型为Optional<Stream的T类型>

  • 遍历:
    • forEach:对每个元素执行操作
  • 匹配与查找
    • allMatch:检查是否匹配所有元素
    • anyMatch:检查是否至少匹配一个元素
    • noneMath:检查是否没有匹配所有元素
    • findFirst:返回第一个元素
    • findAny:返回当前流中的任意元素
  • 统计
    • count:返回流中元素的总数
    • max:返回流中最大值
    • min:返回流中最小值
  • 归约:
    • reduce:对流中的元素按照指定的方式进行归约操作
  • 收集:
    • collect:将流转换为集合或Map等其他类型
  • 分组:
    • groupingBy:按照指定的条件对流进行分组