Stream 是 Java 8 基于函数式编程的核心工具,专门用来高效、优雅地处理集合 / 数组(筛选、排序、转换、聚合、去重等)。
简单理解:把集合 / 数组变成一条 “数据流”,流水线式处理,一行代码搞定复杂操作,告别繁琐的 for 循环!
一、Stream 核心三大特性
- 流水线式操作:多个操作连在一起,一步到位
- 惰性执行:只有调用最终操作,中间逻辑才会执行
- 一次性使用:一个 Stream 只能用一次,用完即废
二、Stream 操作流程(固定套路)
数据源 → 中间操作(筛选/排序/转换...可多个) → 最终操作(结果输出)
- 数据源:集合、数组、文件等
- 中间操作:返回 Stream,可链式拼接
- 最终操作:返回结果(集合、数值、对象等),Stream 结束
三、第一步:创建 Stream(数据源)
1. 集合创建(最常用)
java
运行
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream(); // 串行流
Stream<String> parallelStream = list.parallelStream(); // 并行流
2. 数组创建
java
运行
String[] arr = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(arr);
3. 静态方法创建
java
运行
Stream<String> stream = Stream.of("a", "b", "c");
四、第二步:常用中间操作(核心!)
返回 Stream,可链式拼接,重点掌握这 6 个:
1. filter:筛选(条件过滤)
接收 Predicate,保留满足条件的数据
java
运行
List<Integer> list = Arrays.asList(1, 5, 8, 12, 15);
// 筛选 > 10 的数字
list.stream().filter(num -> num > 10);
2. map:转换(提取 / 类型转换)
接收 Function,把数据转成另一种形式
java
运行
// 字符串 → 长度
list.stream().map(s -> s.length());
// 对象 → 属性(开发最常用)
userList.stream().map(User::getName);
3. sorted:排序
java
运行
// 自然排序(升序)
list.stream().sorted();
// 自定义排序(年龄降序)
userList.stream().sorted((u1, u2) -> u2.getAge() - u1.getAge());
4. distinct:去重
java
运行
list.stream().distinct();
5. limit:限制条数
java
运行
// 取前 3 条
list.stream().limit(3);
6. skip:跳过条数
java
运行
// 跳过前 2 条
list.stream().skip(2);
五、第三步:常用最终操作(必须有!)
返回最终结果,执行后 Stream 关闭:
1. collect:收集结果(最常用)
转成 List/Set/Map
java
运行
// 转 List
List<String> resultList = stream.collect(Collectors.toList());
// 转 Map(key=name,value=user)
Map<String, User> userMap = userList.stream()
.collect(Collectors.toMap(User::getName, u -> u));
2. forEach:遍历
接收 Consumer
java
运行
stream.forEach(System.out::println);
3. count:计数
java
运行
long count = stream.count();
4. reduce:聚合(求和 / 最大 / 最小)
接收 BinaryOperator
java
运行
// 求和
int sum = list.stream().reduce(0, Integer::sum);
// 最大值
int max = list.stream().reduce(Integer::max).get();
5. anyMatch /allMatch/noneMatch:判断
接收 Predicate
java
运行
// 是否有任意一个满足
boolean any = stream.anyMatch(num -> num > 10);
// 是否全部满足
boolean all = stream.allMatch(num -> num > 10);
6. findFirst /findAny:查找
java
运行
// 获取第一个
Optional<Integer> first = stream.findFirst();
六、实战:一行代码完成复杂操作(必看)
需求:用户集合 → 筛选成年 → 按年龄降序 → 提取姓名 → 转 List
java
运行
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
class User {
private String name;
private int age;
// 构造、getter
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
public class StreamTest {
public static void main(String[] args) {
List<User> userList = Arrays.asList(
new User("张三", 16),
new User("李四", 22),
new User("王五", 19),
new User("赵六", 25)
);
// Stream 一行搞定!
List<String> adultNameList = userList.stream()
.filter(u -> u.getAge() >= 18) // 1.筛选成年
.sorted((u1, u2) -> u2.getAge() - u1.getAge()) // 2.降序
.map(User::getName) // 3.提取姓名
.collect(Collectors.toList()); // 4.转List
System.out.println(adultNameList); // [赵六, 李四, 王五]
}
}
七、Stream 常用聚合操作(开发必备)
java
运行
List<Integer> list = Arrays.asList(1,2,3,4,5);
// 求和
int sum = list.stream().mapToInt(Integer::intValue).sum();
// 最大值
int max = list.stream().mapToInt(Integer::intValue).max().getAsInt();
// 最小值
int min = list.stream().mapToInt(Integer::intValue).min().getAsInt();
// 平均值
double avg = list.stream().mapToInt(Integer::intValue).average().getAsDouble();
八、中间操作 vs 最终操作(快速区分)
表格
| 类型 | 返回值 | 特点 | 例子 |
|---|---|---|---|
| 中间操作 | Stream | 不执行,只拼接 | filter、map、sorted |
| 最终操作 | 具体结果 | 触发执行,关闭流 | collect、forEach、count |
口诀:没有最终操作,Stream 等于白写!
九、核心总结(一句话吃透)
- Stream = 集合的流水线工具,专门简化集合操作
- 固定流程:创建 → 中间操作(筛选 / 转换 / 排序) → 最终操作(结果)
- 核心中间操作:
filter(筛选)、map(转换)、sorted(排序) - 核心最终操作:
collect(收集)、forEach(遍历)、reduce(聚合) - 优点:代码极简、可读性高、支持并行高效
终极口诀
集合处理不用愁,Stream 流水线解千愁;筛选转换加排序,一行代码全搞定!