1. 引言
Java Stream 是 Java 8 引入的一种新的抽象,它使得对集合数据的处理更加简洁和高效。Stream API 提供了丰富的操作方法,能够以声明性的方式操作数据集合。本文将详细介绍 Java Stream 流中几种常见的操作方法,包括 map()
、filter()
、reduce()
等,帮助读者深入理解其使用方法和应用场景。
2. map() 方法
map()
方法是一种中间操作,它接收一个函数作为参数,该函数会被应用到流中的每一个元素上,并将其映射为一个新的元素。可以用来将一种类型的元素转换为另一种类型,或者对元素进行重新组合。示例代码如下:
在上述示例中,map(String::toUpperCase)
将每个字符串都转换为大写形式,并返回一个新的流,最终通过 collect()
方法将结果收集为一个列表。
3. filter() 方法
filter()
方法用于通过传入的条件过滤流中的元素,保留满足条件的元素。它也是一种中间操作。示例代码如下:
在上面的例子中,filter(num -> num % 2 == 0)
过滤出了所有偶数,保留满足条件 num % 2 == 0
的元素,然后收集到一个新的列表中。
4. reduce() 方法
reduce()
方法是一种终端操作,它可以将流中的元素通过指定的操作,合并成一个结果。它可以用来求和、求最大值、最小值等。示例代码如下:
在上述示例中,reduce(0, (a, b) -> a + b)
将流中所有元素进行累加求和,初始值为0,Lambda 表达式 (a, b) -> a + b
定义了如何将两个元素相加。
5. sorted() 方法
sorted()
方法用于对流中的元素进行排序操作,它是一种中间操作。示例代码如下:
在上面的例子中,sorted()
方法对整数列表进行升序排序,并将排序后的结果收集到一个新的列表中。
6. forEach() 方法
forEach()
方法是一种终端操作,它接收一个 Lambda 表达式作为参数,对流中的每个元素执行指定的操作。示例代码如下:
在上面的例子中,forEach(System.out::println)
对流中的每个字符串元素调用 println()
方法进行输出。
7. count() 方法
count()
方法是一种终端操作,它返回流中的元素个数。示例代码如下:
在上述示例中,count()
方法返回列表 names
中元素的个数。
8. flatMap() 方法
flatMap()
方法是一种中间操作,它接收一个函数作为参数,将流中的每个元素映射为一个流,然后将所有的流连接成一个流。通常用于处理嵌套结构的数据。示例代码如下:
在上述示例中,flatMap(List::stream)
将嵌套的列表 nestedNumbers
扁平化为一个包含所有整数的流,并将其收集到一个列表中。
9. distinct() 方法
distinct()
方法是一种中间操作,用于去除流中重复的元素,保留唯一的元素。示例代码如下:
在上面的例子中,distinct()
方法去除了列表 numbers
中的重复元素,并将结果收集为一个新的列表。
10. skip() 和 limit() 方法
skip()
和 limit()
都是中间操作,用于对流中的元素进行截取和跳过操作。
skip(n)
方法跳过流中的前n
个元素。limit(n)
方法获取流中的前n
个元素。
示例代码如下:
在上述示例中,skip(2)
跳过前两个元素,然后 limit(3)
取流中的前三个元素,并将结果收集到一个新的列表中。
11. anyMatch()、allMatch() 和 noneMatch() 方法
这些方法都是终端操作,用于检查流中的元素是否满足指定的条件。
anyMatch()
方法检查流中是否至少有一个元素满足给定的条件。allMatch()
方法检查流中的所有元素是否都满足给定的条件。noneMatch()
方法检查流中是否没有元素满足给定的条件。
示例代码如下:
12. 并行流处理
Java Stream 还支持并行流处理,通过 parallelStream()
方法来实现。它可以在多核处理器上并行执行流操作,提高处理效率。
示例代码如下:
13. 组合操作
Java Stream 允许多个操作组合在一起,形成复杂的数据处理流程。例如:
14. 使用流的注意事项
- 惰性求值:流的中间操作是惰性的,只有遇到终端操作时才会触发实际的计算。
- 不可重用:流的一旦被消费(即执行了终端操作),便不能再次使用。如果需要多次操作同一组数据,可以创建多个流对象。