定义
可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它
有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表。
- 匿名——我们说匿名,是因为它不像普通的方法那样有一个明确的名称:写得少而想
得多!- 函数——我们说它是函数,是因为Lambda函数不像方法那样属于某个特定的类。但和方
法一样, Lambda有参数列表、函数主体、返回类型,还可能有可以抛出的异常列表。- 传递——Lambda表达式可以作为参数传递给方法或存储在变量中。
- 简洁——无需像匿名类那样写很多模板代码。
在Java中传递代码十分繁琐和冗长。那么,现在有了好消息! Lambda解决了这个问题:它可以让你十分简明地传
递代码。
语法
Lambda
的基本语法是
(parameters) -> expression
或(请注意语句的花括号)
(parameters) -> { statements; }
Lambda表达式由参数、箭头和主体组成
Comparator<Apple> byWeight =
(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
在哪里及如何使用Lambda
- 函数式接口
- 函数描述符
函数式接口就是只定义一个抽象方法的接口,如Runnable和Comparator。
接口现在还可以拥有默认方法(即在类没有对方法进行实现时,
其主体为方法提供默认实现的方法)。哪怕有很多默认方法,只要接口只定义了一个抽象
方法,它就仍然是一个函数式接口。
==@FunctionalInterface==
如果你去看看新的Java API,会发现函数式接口带有@FunctionalInterface的标注(3.4
节中会深入研究函数式接口,并会给出一个长长的列表)。这个标注用于表示该接口会设计成
一个函数式接口。如果你用@FunctionalInterface定义了一个接口,而它却不是函数式接
口的话,编译器将返回一个提示原因的错误。
实例
读取文件内容例子:
- 定义函数式接口BufferedReaderProcess
/**
* @author yinsheng
* @date 2020/1/10 0010
* @desc 文件处理函数式接口
* 第一步:使用函数式接口来传递行为,
*需要创建一个能匹配BufferedReader -> String,还可以抛出IOException异常的接口。
*/
@FunctionalInterface
public interface BufferedReaderProcess {
/**
* @desc 文件处理
* @params 文件流
* @return 文件内容
*/
String process(BufferedReader br) throws Exception;
}
- 文件处理类FileReaderProcess
/**
* @author yinsheng
* @date 2020/1/10 0010
* @desc 文件处理类
*/
public class FileReaderProcess {
private String path;
public FileReaderProcess(String path) {
this.path = path;
}
/**
* @desc 第二步:执行一个行为
* 任何BufferedReader -> String形式的Lambda都可以作为参数来传递,因为它们符合
* BufferedReaderProcessor接口中定义的process方法的签名。现在你只需要一种方法在
* processFile主体内执行Lambda所代表的代码。
* @params
* @return
*/
public String processFile(BufferedReaderProcess bp) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(this.path));
return bp.process(br);
}
public static void main(String[] args) throws Exception {
FileReaderProcess fileReaderProcess = new FileReaderProcess("d:\\a.txt");
/**
* 第三步:传递 Lambda
* 现在你就可以通过传递不同的Lambda重用processFile方法,并以不同的方式处理文件了
*/
String content = fileReaderProcess.processFile((BufferedReader br) -> br.readLine() + br.readLine());
System.out.println("File Content: " + content);
}
}