Stream 是 Java 8 引入的一种新的抽象,用于处理集合类 (Collection) 的数据。Stream 并不存储数据,而是按需计算数据。Stream 操作有两个重要特性:
- 流水线操作 (Pipelining):Stream 操作可以链式调用,形成一个流水线,这些操作既可以是中间操作(intermediate operation),也可以是终端操作(terminal operation)。
- 内部迭代 (Internal Iteration):不同于集合类的外部迭代 (external iteration),Stream 使用内部迭代,通过底层的迭代器实现。
Stream 的优点
- 简洁性:Stream API 提供了声明性的方法链来处理数据,这使得代码更简洁、更易读。
- 易于并行化:Stream API 提供了简单的并行化处理数据的方式,通过 parallelStream 可以轻松实现并行计算,提高处理性能。
- 函数式编程风格:Stream API 支持函数式编程,允许使用 Lambda 表达式和方法引用,减少了样板代码。
- 延迟执行:中间操作是惰性求值的,只有在终端操作执行时才会计算,优化了性能。
- 更高的抽象层次:Stream API 提供了一种更高层次的数据处理抽象,使得代码更具表达力和可维护性。
用途
Stream API 主要用于对集合数据进行操作,比如过滤、排序、映射、归约等。它提供了一种函数式编程的风格,使代码更简洁、易读、可维护。常见用途包括:
- 过滤 (Filtering):从集合中筛选出符合条件的元素。
- 映射 (Mapping):将集合中的每个元素映射成另一种形式。
- 归约 (Reduction):将集合中的元素组合成一个值。
- 收集 (Collecting):将处理后的数据转换为其他集合形式。
- 统计 (Statistics):对数据进行统计计算,如计数、求和、平均值等。
常用的 Stream 操作示例:
1. 创建 Stream
2. 中间操作 (Intermediate Operations)
中间操作会返回一个新的 Stream,它们是惰性求值的,只有在终端操作执行时才会执行。
3. 终端操作 (Terminal Operations)
终端操作会触发 Stream 的计算,并生成一个结果或副作用。
代码案例
案例 1:过滤和映射
案例 2:排序和去重
案例 3:归约操作
案例 4:分组操作
案例 5:并行流
案例 6:生成数列
案例 7:字符串拼接
注意事项
1.排序 stream.sorted()
- 无参的 sorted():元素按照它们的自然顺序排序。如果你的元素是数字或字符串等基本类型,它们将按照自然数值或字典顺序排序。如果你的元素是对象,它们将按照 Comparable 接口中定义的顺序排序。
- 带Comparator的 sorted():元素按照你提供的 Comparator 排序。这允许你定制排序逻辑,例如,你可以按字符串长度排序、按某个属性的逆序排序等。
2.中间操作 (Intermediate Operations) 和 终端操作 (Terminal Operations) 的区别
- 中间操作:
- 返回一个新的 Stream。
- 惰性求值:中间操作本身不会触发实际的计算,只有在终端操作执行时才会计算。
- 例子:filter, map, flatMap, distinct, sorted, limit, skip, peek。
- 终端操作:
- 触发 Stream 的计算,并生成结果。
- 不是惰性求值,一旦调用终端操作,整个 Stream 的计算就会执行。
- 终端操作会关闭 Stream,之后不能再对其进行操作。
- 例子:forEach, toArray, reduce, collect, min, max, count, anyMatch, allMatch, noneMatch, findFirst, findAny。