自从我听说Java8将要支持Lambda表达式(或称闭包),我便开始狂热的想要将这些体面的简洁的功能元素应用到我的代码中来。大多开发者普遍的使用匿名内部类来开发事件处理器,比较器,thread/runnable实现等等,一些没有必要的辅助代码将逻辑复杂化,即便一些非常简单的代码也变的复杂不堪。Java8现在加入了Lambda表达式作为语法的一部分将会极大地解决这一类似问题。
它使得开发者可以封装一个单独的行为单元并且传递给其他代码。他更像是一个匿名类(带有一个方法的可推断类型)的语法糖和一个更少对象的方法。我希望这篇文章不会扯过多广泛的理论材料,但是在理解Lambda的语法,结构和实例前,这里还是有一个非常重要的概念需要注意。
Source Code
下面是一个IntelliJ的项目,包含了该篇文章中所有例子的源码。
下载源码
具体下载目录在 /2014年资料/5月/16日/Java 8 Lambda 表达式示例
函数式接口一个函数式接口 (又或者称单抽象方法类型或者SMA)是任何包含为一个抽象方法的接口. 但它可能包含一些static或者/和default 方法.java.lang.Runnableis是一个函数式接口的例子, 因为他只有一个run()方法, 并且是抽象的. 类似的 ActionListener也是一个函数式接口. 下面是一个用户自定义函数式接口的例子。
interface Worker() {
boolean doWork();
};
喊一下另一个典型的函数式接口的例子:
interface Operator {
TYPE operate(TYPE operand1, TYPE operand2);
}
就是这样, 因为他就是一个含有一个抽象方法的普通接口. 尽管对于函数式接口还有很多需要讨论尤其是java8提供的 java.util.function包和@FunctionalInterface注解,但现在仅仅关注lambdas。我会在另一篇单独的博客中讨论那些话题。
Lambda 表达式Lambda 表达式,也被称为闭包,是为开发者提供用简单和紧凑的方式表示数据的匿名函数。
- Brian Goetz, Specification Lead for JSR 335
为了更容易的了解lambda表达式的语法,我们先来看一下常规的匿名内部类。
new Runnable() {
public void run() {
performWork();
}
};
Lambda 表达式为匿名内部类提供了一个更简洁的实现方法,上面的5行代码可以被转换成下面这一行代码:
() -> performWork();
语法和结构所以,标准的lambda表达式的语法像下面这样:
() -> some expression
或者
(arguments) -> { body just like function }
一个 lambda 表达式有以下三部分组成:
用括号包裹,并以逗号分割的参数列表
// 接受连个整数,并返回它们的和
(int x, int y) -> x + y
// 用一个整数作为参数的lambda表达式,并且返回该整数的下一个整数
(int x) -> { return x + 1; }
在lambda表达式中,你可以省略参数的数据类型。
// 同样的lambda表达式,但是没有了数据类型
(x, y) -> x + y
(x) -> { return x + 1; }
此外,如果只有一个参数的话,你甚至可以将括号省略掉
// 只有一个参数的lambda表达式,并且省略掉了括号
x -> { return x + 1; }
箭头符号,->
//没有参数,并且返回一个常数92的lambda表达式
() -> 92
// 接受一个字符串作为参数,并且将其输出在控制台中
(String s) -> { System.out.println(s); }
函数体(body)——包括至少一句表达式,或这一个表达式块。在表达式中,主体部分被执行,并且返回。
// 一条语句的body,没有必要使用花括号包裹或返回语句。
x -> x + 1
// 简单的lambda表达式,返回值为空
() -> System.out.println(“Hello World!”)
在代码块的形式中,body就像一个方法的body那样被执行,并且返回语句将流程返回到匿名方法的调用处。