文章目录
其言必信,其行必果,其诺必诚。
一、lambda介绍
1.1 lambda表达式
可以把lambda表达式理解为匿名函数。它有参数、有方法体、有返回类型甚至可以返回异常列表,唯一不同的是它没有具体的函数名。
1.2 在哪里使用lambda
可以在函数式接口中使用lambda表达式。
1.2.1 函数式接口
定义:
有且仅有一个抽象方法的接口就是函数式接口。
例如: Runnable、Callable 等。
// 此注解只是用来标注这个接口是函数式接口、只是个标识、没有特殊语义
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
1.2.2 函数描述符
函数式接口的抽象方法的签名基本上就是Lambda表达式的签名。我们将这种抽象方法叫作函数描述符。
例如:Runnable接口就可以看作一个什么也不接受什么也不返回的函数的签名,这是因为它的run抽象方法的定义决定的。
public abstract void run();
我们可以使用以下方式来描述函数式接口的签名,以Runnable接口为例:
()- > void
这正是Runnable接口所代表的。
1.3 如何使用lambda
我们一定不要忘记,使用lambda表达式的目的是为了让程序更灵活、更简洁。
因此,在判断是否应该、能够使用lambda表达式也应该遵循这个原则。其次,lambda表达式之所以能更灵活与「行为参数化」这个概念密不可分。
举个例子:在环绕执行的时候,比如,处理文件的时候,通常需要读取文件,然后执行核心逻辑,最后关闭资源。如下图所示:读取文件,关闭资源操作总是围绕着核心逻辑,这就是环绕执行模式。
从图中可以看出,任务A和B都环绕着读取文件流、关闭资源的同一段冗余代码。
比如,下面这段代码
public void processFile() throws IOException {
File file = ResourceUtils.getFile("classpath:data.text");
FileInputStream fileInputStream = new FileInputStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader reader = new BufferedReader(inputStreamReader);
try {
// 核心代码 输出文件第一行
String s1 = reader.readLine();
System.out.println(s1);
} finally {
reader.close();
inputStreamReader.close();
fileInputStream.close();
}
}
现在,假设任务A是输出文件第一行,任务B是输出文件头两行,我想要复用围绕着的冗余代码,让我们来看看如何使用lambda表达式实现这个目标。
1.3.1 行为参数化
现在任务A和B都是针对文件进行处理,我们将这部分逻辑抽象出来。
前面说过,lambda表达式要配合函数式接口使用,因此,定义如下接口
@FunctionalInterface
public interface FileProcessor {
String process(BufferedReader reader) throws IOException;
}
使用函数式接口来传递行为
// processor 行为参数化,用来传递不同的行为逻辑
public void processFile(FileProcessor processor) throws IOException {
File file = ResourceUtils.getFile("classpath:data.text");
FileInputStream fileInputStream = new FileInputStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader reader = new BufferedReader(inputStreamReader);
try {
// 此方法现在执行不同的业务处理
processor.process(reader);
} finally {
reader.close();
inputStreamReader.close();
fileInputStream.close();
}
}
1.3.2 传递Lambda
// 输出第一行
processFile((BufferedReader reader) -> System.out.println(reader.readLine()));
// 输出前两行
processFile((BufferedReader reader) ->{
System.out.println(reader.readLine());
System.out.println(reader.readLine());
} );
例子实在是粗糙,但我要表达的是我们应该如何利用lambda来优化我们的代码,在日常工作中优化代码,还是需要费些心神的。