Java 8 的 Stream API 是处理集合数据的函数式编程工具,提供高效、声明式的数据处理能力。以下是核心概念和用法详解:
1. 核心特点
声明式编程:描述"做什么"而非"如何做"
不修改源数据:生成新数据流
惰性求值:中间操作延迟执行,终端操作触发计算
可并行化:
parallelStream()
自动并行处理
2. 操作分类
3. 常用操作示例
3.1 过滤与映射
List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
// 过滤长度>5并转为大写
List<String> result = words.stream()
.filter(s -> s.length() > 5)
.map(String::toUpperCase)
.collect(Collectors.toList());
// 输出: [BANANA, CHERRY]
3.2 扁平化处理(flatMap
)
List<List<Integer>> numberLists = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4, 5)
);
List<Integer> flatList = numberLists.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
// 输出: [1, 2, 3, 4, 5]
3.3 归约操作(reduce
)
int sum = IntStream.range(1, 5) // [1,2,3,4]
.reduce(0, (a, b) -> a + b);
// 输出: 10
3.4聚合统计
IntSummaryStatistics stats = Stream.of(1, 4, 2, 7)
.mapToInt(Integer::intValue)
.summaryStatistics();
System.out.println("Avg: " + stats.getAverage()); // 3.5
System.out.println("Max: " + stats.getMax()); // 7
4. 并行流处理
long count = words.parallelStream()
.filter(s -> s.contains("a"))
.count(); // 并行统计包含"a"的单词数
5. 收集器(Collectors)常用操作
分组示例:
Map<Integer, List<String>> byLength = words.stream()
.collect(Collectors.groupingBy(String::length));
// 输出: {5=[apple], 6=[banana, cherry], 4=[date]}
6. 注意事项
流不可复用:终端操作后流即关闭
Stream<Integer> stream = Stream.of(1, 2); stream.forEach(System.out::print); // 正常 stream.count(); // 抛出 IllegalStateException
避免副作用:操作中不要修改外部状态
// 错误示范 (修改外部列表) List<String> output = new ArrayList<>(); words.stream().filter(s -> s.length() > 4).forEach(output::add); // 正确方式 List<String> output = words.stream() .filter(s -> s.length() > 4) .collect(Collectors.toList());
无限流处理:使用
limit()
截断Stream.iterate(0, n -> n + 2) .limit(5) // 限制数量 .forEach(System.out::println); // 0,2,4,6,8
7. 性能建议
小数据量优先使用常规循环
顺序无关时用并行流加速
避免在流中频繁装箱(优先使用
IntStream
/LongStream
)
Stream API 通过链式调用简化集合操作,结合 Lambda 表达式可显著提升代码可读性和简洁性,是大数据处理的高效工具。