lambda表达式是从匿名表达式演化而来,抽象而简洁高效。两者的使用方式相差无几,都是实现某个接口方法,但该接口有前提条件:有且仅有一个方法。若使用JDK版本为8及以上,则该方法不限于interface自带的static和default方法。
匿名内部类
特点
- 必须继承一个父类或实现一个接口
- 每次使用均创建新的匿名内部类对象
格式
new 父类构造器(参数列表)| 接口名() {... }
示例
public interface InnerInterface {
public void test(String str);
default String testDefault(String str) {
return str.toUpperCase();
}
default Integer testDefault(Integer inte) {
return inte * inte;
}
static Double testStatic(Double dou) {
return dou * dou;
}
}
class InnerInterfaceImpl {
public static void main(String[] args) {
InnerInterface inner = new InnerInterface() {
@Override
public void test(String str) {
System.out.println("now is : " + str);
}
};
inner.test(LocalDate.now().toString());
}
}
输出为:now is : 2019-08-22
Lambda表达式
特点
- 省略 new 接口名,简化为 () -> {... }
那么如何判断某个方法入参能使用Lambda表达式呢?其实很简单:只需判断该接口是否为函数是接口即可。
何为函数式接口?
特点
- 要确保接口中有且仅有一个抽象方法即可:
修饰符 interface 接口名 {
public abstract 返回值类型 方法名称(可选参数信息);
// 多个非抽象方法 如 default 及 static方法
default 返回值 methodA(入参) {... }
static 返回值 methodB(入参) {... }
}
- @FunctionalInterface注解
该注解为JDK8专门为函数式接口而引入。该注解可定义于某个接口上,一旦使用,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。
言归正传,我们还是接着聊Lambda表达式,在使用时有以下几点需注意:
- Lambda表达式隐含return关键字。因此,当单个使用时,无需显示写return关键字
- Lambda表达式为一个语句集合时,需显示添加return语句且用{ }将多个表达式括起来
示例如下:
// 返回大写的字符串,隐含return语句
(String s) -> s.toUpperCase();
// 总是返回hello world的无参方法
() -> "hello the world !"
// 多行表达式,用花括号括起来,并显示return
(int x, int y) -> {
int z = x * y;
return x + z;
}
上面的InnerInterface只有一个方法,拥有多个default及static方法,实际上就是一个函数式接口,因此我们换种写法,提炼下代码。
public interface InnerInterface {
public void test(String str);
default String testDefault(String str) {
return str.toUpperCase();
}
default Integer testDefault(Integer inte) {
return inte * inte;
}
static Double testStatic(Double dou) {
return dou * dou;
}
}
class InnerInterfaceImpl {
public static void main(String[] args) {
InnerInterface inner = new InnerInterface() {
@Override
public void test(String str) {
System.out.println("first is : " + str);
}
};
inner.test(LocalDate.now().toString());
// 敲重点 第二种方式
InnerInterface inner1 = (String now) -> System.out.println("second is : " + now);
inner1.test(LocalDate.now().toString());
}
}
输出为:
first is : 2019-08-22
second is : 2019-08-22