Lambda表达式
传递匿名函数的一种方式:没有名称,有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表
Lambda简介
匿名:不像普通的方法那样有一个明确的名称。
函数:Lambda不像普通函数那样属于某一个特定的类。但和方法一样,有参数列表、函数主题、返回类型,
还有可以抛出异常列表。
传递:Lambda表达式可以作为参数传递给方法或者储存于变量中
简洁:无需像匿名类那样写很多代码模板
Lambda结构
Comparator<Apple> byWeight = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
以上展示的Lambda表达式有三个部分
- 参数列表 : 这里它采用了Comparator中compare方法的参数,两个Apple
- 箭头: 箭头->把参数列表与Lambda主体分隔开。
- Lambda主体 : 比较两个Apple的重量。表达式就是Lambda的返回值了。
Lambda语法
语法一:
(parameters)->expression
语法二:
(parameters)->{expression;}
举个栗子
根据上述语法规则,以下哪个不是有效的Lambda表达式?
(1) () -> {}
(2) () -> “Raoul”
(3) () -> {return “Mario”;}
(4) (Integer i) -> return “Alan” + i;
(5) (String s) -> {“IronMan”;}
答案:只有4和5是无效的Lambda。
(1) 这个Lambda没有参数,并返回void。它类似于主体为空的方法:public void run() {}。
(2) 这个Lambda没有参数,并返回String作为表达式。
(3) 这个Lambda没有参数,并返回String(利用显式返回语句)。
(4) return是一个控制流语句。要使此Lambda有效,需要使花括号,如下所示:
(Integer i) -> {return “Alan” + i;}。
(5)“Iron Man”是一个表达式,不是一个语句。要使此Lambda有效,你可以去除花括号
和分号,如下所示:(String s) -> “Iron Man”。或者如果你喜欢,可以使用显式返回语
句,如下所示:(String s)->{return “IronMan”;}。
搞一哈
-
行为参数化
public static String processFile() throws IOException { try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) { return br.readLine(); //做有用工作的代码 } }
注意以上代码,从一个文件中读取一行数据,但是如果想要返回文件的头两行,甚至是返回文件中违规词语,那 咋整了,我们就需要重用获取资源和清理资源的代码,告诉processFile方法对文件执行不同的操作。我们需要把 processFile的行为参数化,我们需要一种方法把行为传递给peocessFile,以便于它可以利用bufferedReader执行不同的行为。 我们需要一个接收BufferedReader并返回String的Lambda,如下:
String result = processFile((BufferedReader br) -> br.readLine() + br.readLine());
-
函数式接口传递行为
Lambda的应用场景是上下文是函数式接口的情况,我们需要创建一个匹配 BufferedReader ->String,还可以抛出IOException异常的接口。@FunctionalInterface public interface BufferedReaderProcessor { String process(BufferedReader b) throws IOException; }
现在我们把这个接口作为process File方法的参数:
public static String processFile(BufferedReaderProcessor p) throws IOException { … }
-
执行一个行为
public static String processFile(BufferedReaderProcessor p) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) { return p.process(br); } }
-
传递lambda
现在我们可通过传递不同的Lambda来重用processFile方法,一不同的方式来处理文件了。处理一行:
String oneLine = processFile((BufferedReader br) -> br.readLine());
处理两行:
String twoLines = processFile((BufferedReader br) -> br.readLine() + br.readLine());