221. Java 函数式编程风格 - 从命令式风格到函数式风格:计算文件中包含指定单词的行数
文章目录
- 221. Java 函数式编程风格 - 从命令式风格到函数式风格:计算文件中包含指定单词的行数
- 🚨 命令式风格实现
- 🧑💻 代码解析
- 🔄 使用 `Stream` 转换数据
- 🧑💻 函数式风格实现
- 🧑💻 代码解析
- ✨ 函数式风格带来的好处
- 🛠 总结
221. Java 函数式编程风格 - 从命令式风格到函数式风格:计算文件中包含指定单词的行数
假设我们需要遍历一个文件,并计算包含指定单词的行数。下面是一个常见的命令式风格代码示例来完成这个任务:
🚨 命令式风格实现
// Sample.java
import java.nio.file.*;public class Sample {public static void main(String[] args) {try {final String filePath = "src/main/java/chapter221/Sample.java";final String wordOfInterest = "public";try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {String line = "";long count = 0;while((line = reader.readLine()) != null) {if(line.contains(wordOfInterest)) {count++;}}System.out.println(String.format("Found %d lines with the word %s", count, wordOfInterest));}} catch(Exception ex) {System.out.println("ERROR: " + ex.getMessage());}}
}
🧑💻 代码解析
在这段命令式代码中,我们执行了两个主要操作:
- 使用
BufferedReader读取文件的内容。 - 在
while循环中检查每一行是否包含指定的单词。如果该行包含目标单词,就增加计数器。
我们可以看到,在 while 循环内有一个 if 条件判断,这通常是函数式风格中可以使用 filter() 方法的地方。接下来,我们将要探讨如何将这种命令式风格的代码转换为更加简洁且函数式的风格。
🔄 使用 Stream 转换数据
要使用函数式风格的流,我们首先需要将文件的内容转换为流数据。幸运的是,Java 早已提供了将文件内容转换为流的功能,这可以通过 Files.lines() 方法来实现。lines() 方法返回一个流,可以通过流操作(如 filter() 和 count())来处理文件内容。
🧑💻 函数式风格实现
我们将前面的命令式风格代码转换为函数式风格,代码如下:
// Sample.java
import java.nio.file.*;public class Sample {public static void main(String[] args) {try {final String filePath = "src/main/java/chapter221/Sample.java";final String wordOfInterest = "public";try (Stream<String> stream = Files.lines(Paths.get(filePath))) {long count = stream.filter(line -> line.contains(wordOfInterest)).count();System.out.println(String.format("Found %d lines with the word %s", count, wordOfInterest));}} catch(Exception ex) {System.out.println("ERROR: " + ex.getMessage());}}
}
🧑💻 代码解析
Files.lines(Path.of(filePath)):此方法返回一个流,表示文件中的每一行。这是函数式编程的一个关键点,因为它允许我们将文件视作一个可以进行流操作的源,而不需要手动迭代每一行。filter(line -> line.contains(wordOfInterest)):在流中应用filter()方法,我们筛选出包含目标单词的行。count():使用count()方法对符合条件的行进行计数。try-with-resources:我们使用try-with-resources来确保流被正确关闭。
✨ 函数式风格带来的好处
通过将数据源(文件的每一行)转换为流,我们不仅简化了代码,还获得了以下好处:
- 简洁性:代码变得更加简洁,去掉了复杂的循环和条件语句,直接用流操作来表达我们的意图。
- 清晰性:函数式风格代码更加声明性,不需要我们手动管理迭代过程,流操作会自动处理。
- 可读性:流式操作(如
filter()和count())清晰地表达了我们对数据的处理逻辑,易于理解。
🛠 总结
- 函数式风格的优势:将命令式风格的代码转换为函数式风格后,代码更加简洁、可读且易于维护。我们通过将文件的每一行转换为流,利用
filter()和count()等流操作完成任务,而无需手动迭代文件内容。 - 流操作的核心概念:通过
Files.lines()我们可以轻松地将外部数据源(如文件)转化为流,这样就可以像处理内存中的数据一样使用流的功能来处理外部资源。 - 提升效率和可维护性:函数式风格不仅使得代码更简洁,还能提升程序的可维护性,尤其是在需要处理大规模数据时,流的操作能高效地进行数据处理和资源管理。
通过这种方式,学员能够掌握如何将传统的命令式风格代码转换为现代的函数式风格代码,不仅提高代码质量,也提升了工作效率。
