216. Java 函数式编程风格 - 从命令式 foreach + if 到函数式风格
🎯 背景说明
在 Java 5 中,我们迎来了更优雅的 foreach 语法:
for (String name : names) {
System.out.println(name);
}
这个语法的本质,是对底层 Iterator 的封装。也就是说,它等效于这样一段更原始的代码:
Iterator<String> it = names.iterator();
while (it.hasNext()) {
String name = it.next();
System.out.println(name);
}
💡 这是命令式风格的代表之一,它告诉计算机 怎么做(how):获取迭代器、循环判断、手动取值、处理逻辑等。
而在函数式编程中,我们更关注 要做什么(what),而把 “怎么做” 留给底层 API 实现。
✅ 基础转换:foreach 到函数式
命令式写法:
for (String name : names) {
System.out.println(name);
}
函数式写法:
names.forEach(System.out::println);
☕
forEach()是Java 8引入的默认方法,Collection和Stream都支持!
🧠 增加过滤逻辑:foreach + if 条件判断
有时候我们不仅遍历集合,还会加上一些条件判断:
for (String name : names) {
if (name.length() > 3) {
System.out.println(name);
}
}
在这种情况下,就需要把 if 转换成函数式风格中的 filter() 操作。
🔁 函数式转换方式:
names.stream()
.filter(name -> name.length() > 3)
.forEach(System.out::println);
💡 解释:
.stream():将集合转为流,开始函数式链式操作。.filter(...):保留满足条件的元素。.forEach(...):对每个符合条件的元素执行操作。
🚀 示例升级
✅ 示例:打印所有以 "A" 开头的名字
命令式写法:
for (String name : names) {
if (name.startsWith("A")) {
System.out.println(name);
}
}
函数式写法:
names.stream()
.filter(name -> name.startsWith("A"))
.forEach(System.out::println);
✅ 示例:把所有长度大于 5 的名字转为大写后打印
names.stream()
.filter(name -> name.length() > 5)
.map(String::toUpperCase)
.forEach(System.out::println);
💡
map()是函数式流处理中的变换操作,用于元素转换。
📌 函数式转换小总结
| 命令式元素 | 函数式替代 |
|---|---|
foreach (T item : list) | list.forEach(...) 或 list.stream().forEach(...) |
if (condition) | .filter(condition) |
| 元素处理逻辑 | .map(...)、.forEach(...) 等 |
🎯 培训练习推荐(互动式)
- 把以下代码转换为函数式风格:
for (String fruit : fruits) {
if (fruit.contains("apple")) {
System.out.println(fruit.toUpperCase());
}
}
函数式提示:你可以组合使用
filter()和map()。
✅ 结语
从 foreach + if 到 stream + filter + forEach 是 Java 函数式编程中最常见、最有价值的转变之一:
- 🔍 更清晰的意图表达(关注 做什么 而不是 怎么做)
- 🧩 易组合、易测试
- 📉 减少冗余代码,提升可读性