转换简单循环
此页面由 Venkat Subramaniam 在 UPL 下贡献命令式与函数式风格
较早版本的 Java 支持面向对象范式与命令式编程风格的混合。从 Java 8 开始,您也可以在代码中混合使用函数式编程风格。如果您的代码库是在 Java 7 或更早版本期间开始的,或者后来由主要熟悉较早版本 Java 的程序员编写,它将充满了命令式风格的代码。
命令式风格是指我们告诉做什么以及如何做。函数式风格本质上是声明式的,我们告诉做什么,并将如何做或细节委托给底层库。命令式风格的代码可能更容易编写,因为我们大多数人都非常熟悉它。但是,代码变得冗长、复杂且难以阅读。函数式风格可能一开始很难,主要是因为大多数程序员不太熟悉它。总的来说,它更容易阅读、理解和更改。随着练习,编写起来也会变得更容易。
在这个 教程系列 中,我们将研究一些常见的命令式风格代码,并找到一个映射或等效的函数式风格代码,我们可以用它来代替。当您使用基于代码的代码时,当您准备好修复错误或进行增强时,您可能会发现将一些命令式风格的代码重构为函数式风格很有用。您可以使用本教程作为指南,为一些常见情况找到命令式到函数式风格的映射。
在本教程中,我们将重点关注简单的循环。
简单的 for 循环
让我们从传统的 for 循环开始,我们在其中对一个范围内索引的值执行操作。
for(int i = 0; i < 5; i++) {
System.out.println(i);
}
在上面的代码中,本质是范围,从 0
到小于 5
的一个值。仪式,噪音,来自 如何,是语法加上索引变量 i
上的增量操作。我们可以保留本质并通过将代码转换为函数式风格来消除仪式。
如果您想使用函数式风格来编写此 for
循环,您可以非常轻松地做到,提示就在代码之前的句子中:索引在一个范围内。由于我们正在遍历一个范围,因此 IntStream
的 range
方法是对此的直接等效项。
import java.util.stream.IntStream;
...
IntStream.range(0, 5)
.forEach(i -> System.out.println(i));
您可以通过对 println
方法使用方法引用来进一步使代码简洁。
import java.util.stream.IntStream;
...
IntStream.range(0, 5)
.forEach(System.out::println);
函数式风格的代码更简洁、更容易阅读,并且与命令式版本相比,此版本的意图更清晰。
如果您的 for
循环运行到包含结束值,就像在以下代码中一样,您可能会想知道。
for(int i = 0; i <= 5; i++) {
System.out.println(i);
}
IntStream
接口为您提供了覆盖,它有一个 rangeClosed
方法专门用于此目的。
import java.util.stream.IntStream;
...
IntStream.rangeClosed(0, 5)
.forEach(System.out::println);
rangeClosed
方法对于从起始值迭代到包含结束值非常有用。
无论您使用 range
方法还是 rangeClosed
方法,您都会获得一个 int
值流,您可以使用内部迭代器在其上执行操作。在本系列的后面,我们将研究超越 forEach
的操作。
在前面的代码示例中,内部迭代器消除了您肩上的迭代负担。流负责一次遍历一个值范围。您只需要专注于对每个元素做什么,因为它们是在 forEach
方法中提供给您的。在我们的示例中,我们只是打印了提供的值。您可以执行任何您喜欢的操作,例如将信息保存到数据库、将其发送到远程服务等。
与 for
循环提供的外部迭代器不同,使用内部迭代器的代码更简洁、噪音更少、避免了显式修改索引变量的需要、更容易阅读、更容易修改,并且更令人愉快地使用。
继续在您自己的代码库中寻找机会,您会在其中看到传统的 for
循环,并将其修改为使用 IntStream
的 range
或 rangeClosed
方法。确保在更改后验证代码按预期工作,最好通过运行您可能已经拥有的自动化测试。
映射
在您看到简单的 for
循环的任何地方,您都可以使用 IntStream
的 range
或 rangeClosed
方法。如果您想迭代到但不包括结束值,请使用 range
方法。使用 rangeClosed
也将结束值包含在您的迭代中。
上次更新: 2023 年 7 月 6 日