Java Stream API 是 Java 8 引入的一项强大的功能,旨在简化集合处理操作,提供对集合进行过滤、映射、排序等操作的高效且简洁的方式。Stream API 允许我们以声明式编程风格来处理数据流,从而提高代码的可读性和可维护性。
Stream API 基本概念
1. **Stream**: 表示数据流,可以是有序或无序的。
2. **Intermediate Operations(中间操作)**: 返回 Stream 的操作,如`filter`、`map`、`sorted`等。这些操作是惰性的,即只有在终端操作执行时才会真正处理数据。
3. **Terminal Operations(终端操作)**: 返回非 Stream 的结果的操作,如`forEach`、`collect`、`reduce`等。一旦终端操作执行,Stream 就不能再被使用。
创建 Stream
Stream 可以从多种数据源创建,如集合、数组、I/O 通道、生成函数等。
```java import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class StreamCreation { public static void main(String[] args) { // 从集合创建 Stream List<String> list = Arrays.asList("a", "b", "c"); Stream<String> streamFromList = list.stream(); // 从数组创建 Stream String[] array = {"d", "e", "f"}; Stream<String> streamFromArray = Arrays.stream(array); // 通过 Stream.of 方法创建 Stream Stream<String> streamOf = Stream.of("g", "h", "i"); // 通过生成函数创建 Stream Stream<Integer> streamIterate = Stream.iterate(0, n -> n + 2).limit(5); // 生成 0, 2, 4, 6, 8 } } ```
常用的中间操作
- `filter`: 过滤元素
- `map`: 转换元素
- `flatMap`: 扁平化操作,将多个 Stream 合并成一个 Stream
- `sorted`: 排序
- `distinct`: 去重
- `limit`: 限制元素数量
- `skip`: 跳过前 n 个元素
```java public class IntermediateOperations { public static void main(String[] args) { List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "elderberry"); // 过滤长度大于5的元素 list.stream() .filter(s -> s.length() > 5) .forEach(System.out::println); // 输出: banana, cherry, elderberry // 将所有元素转换为大写 list.stream() .map(String::toUpperCase) .forEach(System.out::println); // 输出: APPLE, BANANA, CHERRY, DATE, ELDERBERRY // 对元素按字母顺序排序 list.stream() .sorted() .forEach(System.out::println); // 输出: apple, banana, cherry, date, elderberry // 获取前3个元素 list.stream() .limit(3) .forEach(System.out::println); // 输出: apple, banana, cherry } } ```
常用的终端操作
- `forEach`: 遍历元素
- `collect`: 收集结果到集合、数组等
- `reduce`: 归约操作,将 Stream 中的元素组合成一个结果
- `count`: 统计元素个数
- `anyMatch`, `allMatch`, `noneMatch`: 匹配操作
- `findFirst`, `findAny`: 查找操作
```java import java.util.List; import java.util.Optional; import java.util.stream.Collectors; public class TerminalOperations { public static void main(String[] args) { List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "elderberry"); // 遍历元素并打印 list.stream().forEach(System.out::println); // 将所有元素收集到一个新的列表中 List<String> collectedList = list.stream() .filter(s -> s.length() > 5) .collect(Collectors.toList()); System.out.println(collectedList); // 输出: [banana, cherry, elderberry] // 统计元素个数 long count = list.stream().count(); System.out.println(count); // 输出: 5 // 找到第一个以字母 'c' 开头的元素 Optional<String> optional = list.stream() .filter(s -> s.startsWith("c")) .findFirst(); optional.ifPresent(System.out::println); // 输出: cherry // 归约操作,将所有元素连接成一个字符串 String concatenated = list.stream() .reduce("", (acc, elem) -> acc + elem + " "); System.out.println(concatenated.trim()); // 输出: apple banana cherry date elderberry } } ```
并行流
Stream API 提供了并行处理的支持,可以通过调用`parallelStream`或者`stream.parallel()`将流转换为并行流,以利用多核处理器的优势。
```java public class ParallelStreamExample { public static void main(String[] args) { List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "elderberry"); // 使用并行流 list.parallelStream() .filter(s -> s.length() > 5) .forEach(System.out::println); } } ```
总结
Java Stream API 提供了一种声明式的方式来处理集合,使代码更加简洁和易读。通过了解 Stream 的创建、中间操作和终端操作,我们可以在日常工作中更高效地处理数据流。并行流的引入也使得处理大量数据时能够充分利用多核处理器的优势。