Lambda 表达式,Java中应用Lambda 表达式

1、Lambda 表达式javascript

简单来讲,编程中提到的 lambda 表达式,一般是在须要一个函数,可是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。html

连接:知乎java

先举一个普通的 Python 例子:将一个 list 里的每一个元素都平方:express

map( lambda x: x*x, [y for y in range(10)] )

这段代码表达的意思和下面的意思同样:编程

def sq(x):
    return x * x

map(sq, [y for y in range(10)])
若是这个函数只会使用一次的话。并且第一种写法实际上更易读,由于那个映射到列表上的函数具体是要作什么,很是一目了然。若是你仔细观察本身的代码,会发现这种场景其实很常见:你在某处就真的只须要一个能作一件事情的函数而已,连它叫什么名字都可有可无。Lambda 表达式就能够用来作这件事。
进一步讲,匿名函数本质上就是一个函数,它所抽象出来的东西是一组运算。这是什么意思呢?类比:
a = [1, 2, 3]

闭包

f = lambda x : x + 1

等号右边的东西彻底能够脱离等号左边的东西而存在,等号左边的名字只是右边之实体的标识符。若是你能习惯 [1, 2, 3] 单独存在,那么 lambda x : x + 1 也能单独存在其实也就不难理解了,它的意义就是给「某个数加一」这一运算自己。编程语言

如今回头来看 map() 函数,它能够将一个函数映射到一个可枚举类型上面。沿用上面给出的 a 和 f,能够写:
map(f, a)

也就是将函数 f 依次套用在 a 的每个元素上面,得到结果 [2, 3, 4]。如今用 lambda 表达式来替换 f,就变成:
map( lambda x : x + 1, [1, 2, 3] )

这样的写法时,你会发现本身若是能将「遍历列表,给遇到的每一个元素都作某种运算」的过程从一个循环里抽象出来成为一个函数 map,而后用 lambda 表达式将这种运算做为参数传给 map 的话,考虑事情的思惟层级会高出一些来,须要顾及的细节也少了一点。ide

 

2、Java中应用Lambda 表达式函数式编程

这一部分会介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不一样这些内容,函数

首先看一个Java中匿名内部类的示例:

button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
    System.out.println("The button was clicked using old fashion code!");
}
});

这是使用匿名内部类的方法向一个 UI 组件添加 ActionListener,也能够写成:

button.addActionListener( (e) -> {
    System.out.println("The button was clicked. From Lambda expressions !");
});

后一种方式就是采用了Lambda表达式的方法来进行相同的操做。

为何 Java 须要 Lambda 表达式?

若是忽视注解(Annotations)、泛型(Generics)等特性,自 Java 语言诞生时起,它的变化并不大。Java 一直都致力维护其对象至上的特征,在使用过 JavaScript 之类的函数式语言以后,Java 如何强调其面向对象的本质,以及源码层的数据类型如何严格变得更加清晰可感。其实,函数对 Java 而言并不重要,在 Java 的世界里,函数没法独立存在。在函数式编程语言中,函数是一等公民,它们能够独立存在,你能够将其赋值给一个变量,或将他们当作参数传给其余函数。JavaScript 是最典型的函数式编程语言。点击此处以及此处能够清楚了解 JavaScript 这种函数式语言的好处。函数式语言提供了一种强大的功能——闭包,相比于传统的编程方法有不少优点,闭包是一个可调用的对象,它记录了一些信息,这些信息来自于建立它的做用域。Java 如今提供的最接近闭包的概念即是 Lambda 表达式,虽然闭包与 Lambda 表达式之间存在显著差异,但至少 Lambda 表达式是闭包很好的替代者。

Lambda表达式:

Lambda 表达式是一种匿名函数(对 Java 而言这并不彻底正确,但如今姑且这么认为),简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。

你能够将其想作一种速记,在你须要使用某个方法的地方写上它。当某个方法只使用一次,并且定义很简短,使用这种速记替代之尤为有效,这样,你就没必要在类中费力写声明与方法了。

Java 中的 Lambda 表达式一般使用 (argument) -> (body) 语法书写,例如:

(arg1, arg2...) -> { body }

(type1 arg1, type2 arg2...) -> { body }

或者能够写做:

(int a, int b) -> {  return a + b; }

() -> System.out.println("Hello World");

(String s) -> { System.out.println(s); }

() -> 42

() -> { return 3.1415 };
  • 一个 Lambda 表达式能够有零个或多个参数
  • 参数的类型既能够明确声明,也能够根据上下文来推断。例如:(int a)(a)效果相同
  • 全部参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
  • 空圆括号表明参数集为空。例如:() -> 42
  • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
  • Lambda 表达式的主体可包含零条或多条语句
  • 若是 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
  • 若是 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(造成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

使用Lambda表达式后,线程能够经过如下方法初始化:

//旧方法:
new Thread(new Runnable() {
@Override
public void run() {
    System.out.println("Hello from thread");
}
}).start();

//新方法:
new Thread(
() -> System.out.println("Hello from thread")
).start();
相关文章
相关标签/搜索