java8新特性之lambda表达式与函数式接口

前言

 本文的思路是先介绍lambda重要特征并给出实际用例,再介绍lambda与函数式接口的关系引出函数式接口,再叙述函数式接口的相关特点。

lambda重要特征

1、可选的大括号 

java8新特性之lambda表达式与函数式接口

当方法体内只包含了一个语句时,可以选择省略大括号,方法体末尾不需要分号。如上例,System.out.println("lambda1")语句就没有用大括号括起来,语句末尾也没有分号。

如果方法体有多行,就要用{}括起来,末尾也要跟上分号。

java8新特性之lambda表达式与函数式接口

 2、可选的类型声明

lambda表达式有类型推断机制,在上下文信息足够多的情况下能够推断出参数表的类型而无需指明。

比如Collections.sort()

java8新特性之lambda表达式与函数式接口

可以指明a和b的参数类型为String

java8新特性之lambda表达式与函数式接口 

也可以省略参数类型,因为java可以根据list的类型推断出s1和s2的参数类型

3、 可选的参数圆括号

只有一个参数时可以省略参数圆括号,无参或是多参都要写上圆括号

4、可选的参数关键字

如果方法体只有一个表达式并且未使用大括号,那么编译器会自动返回值。

java8新特性之lambda表达式与函数式接口

 

 什么时候可以简写为lambda

我们分别来看两个匿名内部类的简写,分析为什么它们可以简写成lambda,总结出什么情况下可以简写为lambda。

java8新特性之lambda表达式与函数式接口简写为

java8新特性之lambda表达式与函数式接口

java8新特性之lambda表达式与函数式接口

java8新特性之lambda表达式与函数式接口

观察上面两个匿名内部类,我们可以发现:它们的接口名以及方法名都被擦拭掉了。所以我们可以得出:可以被简写的接口中的抽象方法唯一,因为不唯一的话方法名被擦拭了那就无法识别是哪个方法了。这也就是我们的函数式接口:只有一个抽象方法的接口(不包含一些特殊情况,这些特殊情况下面会介绍)。

函数式接口

JDK1.8前的函数式接口:

java8新特性之lambda表达式与函数式接口

 JDK1.8新定义的函数式接口:

java8新特性之lambda表达式与函数式接口

 

 

函数式接口是只能有一个抽象方法的接口,但这也有例外,接口可以定义Object类的public方法,但这些方法的方法签名必须和Object类的一样,这些方法也是抽象方法,但并不影响该接口成为函数式接口:

java8新特性之lambda表达式与函数式接口

该接口虽然多出了hashCode这个抽象方法,但仍是函数式接口,因为hashCode是Object类的public方法。

 

 

 接口中的抽象方法和默认方法不会影响该接口成为函数式接口:

java8新特性之lambda表达式与函数式接口

该接口中虽然有print这个默认方法,print1这个抽象方法,但仍是函数式接口。

 

 

@FunctionnalInterface作用 

函数式接口可以不用@FunctionalInterface注解修饰,非函数式接口一定不能用@FunctionalInterface修饰,因为@FunctionalInterface会在编译期检查该接口是否为函数式接口,如果不是,则会编译错误。