在 Java 中,Stream(流)是 Java 8 引入的一个强大的 API,用于以声明式方式处理集合(如 List、Set、Array 等)或任何数据源(如文件、I/O 等)。它的核心思想是让开发者可以像操作数据库查询一样,用 链式调用(方法链) 来处理数据,而不必关心底层实现。
1. Stream 的核心特点
-
不是数据结构,不存储数据,而是对数据源(如集合、数组)进行计算。
-
不会修改原始数据,而是返回一个新的流。
-
延迟执行(Lazy Evaluation):只有遇到 终止操作(Terminal Operation) 时才会真正执行计算。
-
支持并行处理(parallelStream()),可以自动利用多核 CPU 加速计算。
2. Stream 的三种操作
Stream 的操作分为三类:
-
创建流(Stream Creation)
从集合、数组、I/O 等创建流。
-
中间操作(Intermediate Operations)
对流进行过滤、映射、排序等操作,返回一个新的流。
-
终止操作(Terminal Operations)
最终计算结果(如 collect、forEach、reduce),执行后流就不能再用了。
3. 如何创建 Stream?
(1) 从集合创建
List<String> list = Arrays.asList("A", "B", "C");
Stream<String> stream = list.stream(); // 顺序流
Stream<String> parallelStream = list.parallelStream(); // 并行流
(2) 从数组创建
String[] array = {"A", "B", "C"};
Stream<String> stream = Arrays.stream(array);
(3) 从值直接创建
Stream<String> stream = Stream.of("A", "B", "C");
(4) 从文件创建
Stream<String> lines = Files.lines(Paths.get("file.txt"));
4. 常见的中间操作
方法 | 说明 | 示例 |
---|---|---|
filter(Predicate) | 过滤符合条件的元素 | .filter(s -> s.startsWith(“A”)) |
map(Function) | 转换元素(1对1映射) | .map(String::toUpperCase) |
flatMap(Function) | 扁平化流(1对多映射) | .flatMap(list -> list.stream()) |
distinct() | 去重 | .distinct() |
sorted() | 排序 | .sorted() |
limit(n) | 取前 n 个元素 | .limit(3) |
skip(n) | 跳过前 n 个元素 | .skip(2) |
5. 常见的终止操作
方法 | 说明 | 示例 |
---|---|---|
forEach(Consumer) | 遍历每个元素 | .forEach(System.out::println) |
collect(Collector) | 收集结果(如转 List、Set) | .collect(Collectors.toList()) |
toArray() | 转数组 | .toArray(String[]::new) |
count() | 计算元素数量 | .count() |
reduce(BinaryOperator) | 归约(如求和、最大值) | .reduce(0, Integer::sum) |
anyMatch(Predicate) | 是否有任意元素匹配 | .anyMatch(s -> s.equals(“A”)) |
allMatch(Predicate) | 是否所有元素匹配 | .allMatch(s -> s.length() > 0) |
noneMatch(Predicate) | 是否没有元素匹配 | .noneMatch(s -> s.isEmpty()) |
findFirst() | 返回第一个元素 | .findFirst() |
findAny() | 返回任意一个元素 | .findAny() |
6. 实际应用示例
(1) 过滤 + 映射
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Dave");
List<String> result = names.stream()
.filter(name -> name.length() > 3) // 过滤长度 >3 的名字
.map(String::toUpperCase) // 转大写
.collect(Collectors.toList()); // 收集为 List
System.out.println(result); // [ALICE, CHARLIE, DAVE]
(2) 排序 + 去重
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);
List<Integer> sortedUnique = numbers.stream()
.sorted() // 升序排序
.distinct() // 去重
.collect(Collectors.toList());
System.out.println(sortedUnique); // [1, 2, 3, 4, 5, 6, 9]
(3)求和
int sum = numbers.stream()
.reduce(0, Integer::sum); // 0 是初始值,Integer::sum 是累加方法
System.out.println(sum); // 31