以前处理集合,就是for循环里面套if,if里面再套for,代码缩进好几层,看得人头昏眼花。Java 8的Stream API像是一股清流,让我体会到了声明式编程的魅力。
1. 一个经典的对比:过滤出年龄大于18岁的用户的名字列表
- 传统命令式编程(怎么做):
List<String> nameList = new ArrayList<>();
for (User user : userList) {
if (user.getAge() > 18) {
nameList.add(user.getName());
}
}我们需要自己创建集合,自己遍历,自己判断,自己添加。我们关心的是“怎么做”的每一个步骤。
- Stream API声明式编程(做什么):
List<String> nameList = userList.stream() // 获取流
.filter(user -> user.getAge() > 18) // 过滤:我只要大于18岁的
.map(User::getName) // 映射:把User对象转换成姓名
.collect(Collectors.toList()); // 收集:把结果变成一个List- 代码像一条流水线,我们只需要声明我们“要做什么”,而不关心底层如何迭代。逻辑清晰,一气呵成。
2. Stream的核心操作:三步走
- 创建流:
collection.stream(),Arrays.stream(),Stream.of() 中间操作(懒加载): 对流进行过滤、映射等处理,返回一个新的流。
filter(Predicate p):过滤map(Function f):映射,将元素转换成其他形式sorted():排序distinct():去重
终端操作: 产生最终结果或副作用。
collect(Collectors.toList()):收集为ListforEach(Consumer c):遍历每个元素count():计数findFirst():找第一个元素
3. 一个更复杂的例子:按部门分组,统计平均工资
- 传统方式: 各种Map嵌套,循环,非常复杂。
- Stream方式:
Map<String, Double> avgSalaryByDept = employeeList.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment, // 按部门分组
Collectors.averagingDouble(Employee::getSalary) // 对每组的工资求平均
));- 一行代码搞定,意图非常明确!
总结:
Stream API让集合操作变得高效、易读且易于并行化。虽然初学时有门槛,但一旦掌握,你就会发现再也回不去那个满是循环嵌套的世界了。这是现代Java程序员必须掌握的技能。