让我们通过一个例子,资源处理(例如处理文件或数据库)时一个常见的模式就是打开一个资源,做一些处理,然后关闭资源。这个设置和清理阶段总是很类似,并且会围绕着执行处理的那些重要代码。这就是所谓的环绕执行(execute around)模式
例如,从一个文件中读取一行所需的模板代码
public static String processFile() throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
return br.readLine();
}
}
如何利用Lambda和行为参数化来让代码更为灵活,更为简洁。
第一步:行为参数化
String result =processFile((BufferedReader br) ->br.readLine() + br.readLine());
第二步:使用函数式接口来传递行为
@FunctionalInterface
public interface BufferedReaderProcessor {
String process(BufferedReader b) throws IOException;
}
第三步:执行一个传递进来的行为
任何BufferedReader -> String形式的Lambda都可以作为参数来传递,因为它们符合BufferedReaderProcessor接口中定义的process方法的定义。接下来你只需要在processFile主体内执行Lambda所代表的代码。请记住,Lambda表达式允许你直接内联,为函数式接口的抽象方法提供实现,并且将整个表达式作为函数式接口的一个实例。因此,你可以在processFile主体内,对得到的BufferedReaderProcessor对象调用process方法执行处理:
public static String processFile(BufferedReaderProcessor p) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
return p.process(br);
}
}
第四步:调用processFile方法时,传递自己行为Lambda表达式
现在就可以通过传递不同的Lambda重用processFile方法,并以不同的方式处理文件了。
获取处理文件一行:
String oneLine = processFile((BufferedReader br) -> br.readLine());
获取处理文件两行:
String twoLines = processFile((BufferedReader br) -> br.readLine() + br.readLine());
。
。
。
这样使我们的封装的processFile方法变得十分的灵活和简洁。