Java Stream API:现代化集合处理的艺术
引言
在Java 8中引入的Stream API彻底改变了我们处理集合数据的方式。它不仅仅是一个新的工具集,更代表了一种声明式、函数式的编程范式。本文将深入探讨Java Stream的核心概念、使用场景和最佳实践。
一、什么是Stream?
Stream(流)不是数据结构,而是对数据源(集合、数组、I/O资源等)的元素序列进行函数式操作的一种抽象。与传统的集合操作不同,Stream具有以下特点:
- 惰性执行:中间操作不会立即执行,只有遇到终端操作时才会触发计算
- 不可复用:一个Stream只能被消费一次
- 无存储:Stream本身不存储数据,数据存储在底层集合或由生成器生成
二、Stream操作类型
Stream操作分为两类:
1. 中间操作(Intermediate Operations)
返回新Stream的操作,可以链式调用:
List<String> filtered = list.stream()
.filter(s -> s.length() > 3) // 过滤
.map(String::toUpperCase) // 映射
.sorted() // 排序
.collect(Collectors.toList()); // 终端操作
常用中间操作:
filter(Predicate<T>)
:过滤元素map(Function<T,R>)
:元素转换flatMap(Function<T,Stream<R>>)
:扁平化转换distinct()
:去重sorted()
/sorted(Comparator)
:排序peek(Consumer<T>)
:查看元素但不修改
2. 终端操作(Terminal Operations)
触发实际计算并返回非Stream结果:
long count = list.stream().count(); // 计数
list.stream().forEach(System.out::println); // 遍历
Optional<String> max = list.stream().max(Comparator.naturalOrder());
常用终端操作:
collect(Collector)
:转换为集合或其他形式forEach(Consumer<T>)
:遍历reduce(BinaryOperator<T>)
:归约min()
/max()
:极值count()
:计数anyMatch()
/allMatch()
/noneMatch()
:匹配检查findFirst()
/findAny()
:查找元素