212. Java 函数式编程风格 - Java 编程风格转换:命令式 vs 函数式(以循环为例)

文章目录

  • [212. Java 函数式编程风格 - Java 编程风格转换:命令式 vs 函数式(以循环为例)](#212. Java 函数式编程风格 - Java 编程风格转换:命令式 vs 函数式(以循环为例))
    • [🎯 命令式 vs 函数式编程风格](#🎯 命令式 vs 函数式编程风格)
      • [✅ 命令式(Imperative)](#✅ 命令式(Imperative))
      • [✅ 函数式(Functional / Declarative)](#✅ 函数式(Functional / Declarative))
    • [🔄 为什么要从命令式转向函数式?](#🔄 为什么要从命令式转向函数式?)
    • [🔁 示例对比:转换常见的循环代码](#🔁 示例对比:转换常见的循环代码)
      • [🌟 场景一:从列表中取出所有长度` > 3 `的字符串](#🌟 场景一:从列表中取出所有长度> 3的字符串)
      • [🌟 场景二:将所有字符串转换为大写并输出](#🌟 场景二:将所有字符串转换为大写并输出)
      • [🌟 场景三:找出第一个长度大于` 4` 的名字(如果有)](#🌟 场景三:找出第一个长度大于 4 的名字(如果有))
    • [🚀 小技巧:转型建议](#🚀 小技巧:转型建议)
    • [🧠 总结:何时用函数式风格?](#🧠 总结:何时用函数式风格?)

212. Java 函数式编程风格 - Java 编程风格转换:命令式 vs 函数式(以循环为例)


🎯 命令式 vs 函数式编程风格

Java8 之前,主要支持的是 面向对象 + 命令式编程 。而从 Java 8 开始,引入了 函数式编程风格(Functional Programming) ,让我们可以使用 lambda 表达式、Stream API 等现代特性来简洁、表达式化地处理数据。

✅ 命令式(Imperative)

  • 告诉计算机做什么 ,也要告诉它怎么做
  • 通常是通过显式的 forwhile 循环来完成。
  • 比如:拿出列表中的偶数,加 1,存到新列表中。
java 复制代码
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = new ArrayList<>();
for (int number : numbers) {
    if (number % 2 == 0) {
        result.add(number + 1);
    }
}
System.out.println(result); // [3, 5]

✅ 函数式(Functional / Declarative)

  • 告诉计算机做什么 ,但不关心怎么做
  • 借助 Stream API,使用 filtermapcollect 等操作。
  • 更接近自然语言的描述,可读性高。
java 复制代码
List<Integer> result = numbers.stream()
    .filter(n -> n % 2 == 0)
    .map(n -> n + 1)
    .collect(Collectors.toList());

System.out.println(result); // [3, 5]

🔄 为什么要从命令式转向函数式?

命令式风格的劣势 🚫 函数式风格的优势 ✅
冗长、嵌套复杂 简洁、清晰表达意图
代码可读性差 更易维护、修改和调试
易引入状态错误 更少副作用,更安全

函数式风格最初看起来可能有点陌生,但一旦掌握,就会发现它更符合人类的表达方式,也更容易组合、调试、并行化。


🔁 示例对比:转换常见的循环代码

🌟 场景一:从列表中取出所有长度> 3的字符串

命令式版本:
java 复制代码
List<String> names = Arrays.asList("Tom", "Jerry", "Spike", "Tyke");
List<String> result = new ArrayList<>();

for (String name : names) {
    if (name.length() > 3) {
        result.add(name);
    }
}

System.out.println(result); // [Jerry, Spike]
函数式版本:
java 复制代码
List<String> result = names.stream()
    .filter(name -> name.length() > 3)
    .collect(Collectors.toList());

System.out.println(result); // [Jerry, Spike]

🌟 场景二:将所有字符串转换为大写并输出

命令式:
java 复制代码
for (String name : names) {
    System.out.println(name.toUpperCase());
}
函数式:
java 复制代码
names.stream()
    .map(String::toUpperCase)
    .forEach(System.out::println);

🌟 场景三:找出第一个长度大于 4 的名字(如果有)

命令式:
java 复制代码
String result = null;
for (String name : names) {
    if (name.length() > 4) {
        result = name;
        break;
    }
}
System.out.println(result); // Spike
函数式:
java 复制代码
Optional<String> result = names.stream()
    .filter(name -> name.length() > 4)
    .findFirst();

result.ifPresent(System.out::println); // Spike

🚀 小技巧:转型建议

如果你已经有了命令式的代码,不妨遵循以下步骤来重构为函数式风格:

  1. 识别循环的目的:是过滤?变换?聚合?
  2. 查找可替代的 Stream 方法 :如 filtermapreduce
  3. 消除中间变量:尽量用链式调用,保持表达力。
  4. 保持语义清晰:不要过度压缩代码,避免可读性差。

🧠 总结:何时用函数式风格?

使用函数式风格的最佳时机:

✅ 当你要对集合进行过滤、映射、聚合操作时

✅ 当你希望代码更简洁、更少状态管理

✅ 当你在重构旧代码、修 bug 或加新功能时

使用函数式风格不仅是语法优化,更是思维方式的升级

相关推荐
w***4812 分钟前
CVE-2024-38819:Spring 框架路径遍历 PoC 漏洞复现
java·后端·spring
亮子AI5 分钟前
【Javascript】jsondiffpatch检测到子节点改变了,父节点会标记为改变吗?
开发语言·前端·javascript
caron410 分钟前
C++ 推箱子游戏
开发语言·c++·游戏
JienDa12 分钟前
JienDa聊PHP:PHP从入门到精通—PHP开发入门:从环境搭建到第一个程序
开发语言·php
架构师沉默14 分钟前
为什么工作 10 年都没遇过分布式锁?
java·后端·架构
镜花水月linyi22 分钟前
synchronized 锁升级原理:从 JDK 8 实现到 JDK 25 演进
java·后端·java ee
ERP老兵-冷溪虎山23 分钟前
Python/JS/Go/Java同步学习(第五十篇半)四语言“path路径详解“对照表: 看完这篇定位文件就通透了(附源码/截图/参数表/避坑指南)
java·javascript·python·golang·中医编程·编程四语言同步学·path路径详解
零匠学堂202524 分钟前
移动学习平台与在线学习平台是什么?主要有哪些功能?
java·spring boot·学习
少平81828 分钟前
一分钱的Bug(求助帖)
java
Data_agent30 分钟前
1688获得1688公司档案信息API,python请求示例
开发语言·数据库·python