217. Java 函数式编程风格 - 从命令式到函数式:基于条件选择元素

217. Java 函数式编程风格 - 从命令式到函数式:基于条件选择元素

📝 命令式风格的 if 选择

假设在遍历集合时,我们想根据某个条件筛选出一些元素。比如,我们只希望打印出长度为 4 的名字。在命令式风格中,我们可以使用 if 语句来实现这一点,如下所示:

java 复制代码
List<String> names = List.of("Jack", "Paula", "Kate", "Peter");

for (String name : names) {
    if (name.length() == 4) {
        System.out.println(name);
    }
}

在这个命令式的例子中,我们遍历了 names 集合中的每个元素,并使用 if 判断条件来选择出符合条件(即长度为 4)的名字,然后打印出来。


🔄 转换为函数式风格

在函数式风格中,if 语句可以通过 Streamfilter() 方法来实现。filter() 方法会将满足条件的元素"放行",不满足条件的元素则会被丢弃。通过 filter(),我们可以避免显式地使用 if 语句,使代码更加简洁和流畅。

将上面的命令式代码转换为函数式风格如下:

java 复制代码
List<String> names = List.of("Jack", "Paula", "Kate", "Peter");

names.stream()
     .filter(name -> name.length() == 4)  // 过滤长度为 4 的名字
     .forEach(System.out::println);  // 打印符合条件的名字

💡 解释

  • names.stream():我们先将集合转为流。
  • filter(name -> name.length() == 4)filter() 方法接受一个谓词(Predicate),它会检查每个元素是否满足条件。如果满足(即名字长度为 4),该元素将被传递到下一个操作,否则会被过滤掉。
  • forEach(System.out::println):对每个符合条件的元素执行 println 操作。

🧩 filter() 方法作为条件的替代

filter() 方法像一个过滤网,它决定哪些元素能通过,哪些会被丢弃。通过链式调用,我们可以轻松地在流中进行条件筛选。这种方法将 if 语句的条件判断内置在流操作中,使得代码更加简洁、清晰。

进一步的优化:更复杂的筛选条件

假设我们不仅仅想过滤出长度为 4 的名字,还想过滤出所有包含字母 a 的名字。我们可以将多个 filter() 操作链式调用,形成更复杂的条件筛选。

java 复制代码
names.stream()
     .filter(name -> name.length() == 4)  // 先筛选长度为 4 的名字
     .filter(name -> name.contains("a"))  // 然后筛选包含字母 "a" 的名字
     .forEach(System.out::println);  // 打印符合条件的名字

解释 :通过链式调用的方式,先使用第一个 filter() 筛选出长度为 4 的名字,再通过第二个 filter() 筛选出包含字母 a 的名字,最终将所有符合这两个条件的名字打印出来。


📋 总结:命令式与函数式风格对比

命令式风格 函数式风格
使用 for-each 循环和显式的 if 判断条件 使用 filter() 方法筛选符合条件的元素
迭代过程由程序员手动控制,条件判断显式 迭代过程由流的内部机制自动管理,条件判断内置于流操作中
代码较为冗长,尤其是当条件变复杂时 代码更加简洁、清晰,适合进行链式操作

🎯 结论

通过使用 filter() 方法,我们可以更优雅地进行条件筛选,而不再需要显式地使用 if 语句。将命令式风格转化为函数式风格后,代码变得更加简洁、易于维护,同时也更加符合流式编程的思维方式。

相关推荐
秃头网友小李3 小时前
前端难点:Element Plus 样式覆盖 —— :deep()、CSS 变量与滚动状态类名
前端·vue.js
星哥的编程之路3 小时前
别再调 API 就说自己会 RAG 了,看看真正的企业级 AI 智能体长什么样
后端·面试
the_answer3 小时前
XSS 与 CSRF 深度解析
前端
长大19883 小时前
C++26 静态反射完整实战:告别宏代码生成,一键实现序列化
后端
yb7793 小时前
Java 21 虚拟线程最佳实践:虚拟线程如何让高并发 Java 服务更轻更快
后端
fliter3 小时前
绕过系统 ICMP:用 rawsock、Npcap 和 WMI 找到默认网卡
后端
AHRIKNOW3 小时前
AFaster:一个开箱即用的 Rust 高性能后端框架模板
后端
打呵欠的猫3 小时前
AI 生成的代码你敢直接上线吗?我总结出 3 条铁律
前端·ai编程
小强19883 小时前
C++20 协程从入门到网络服务
后端
鱼人3 小时前
C++ 内存模型详解:原子操作、内存屏障
后端