在谈lamada表达式之前,有必要先了解下什么是函数式接口。为了支持函数式编程,JDK8 新增了一个函数式接口FunctionalInterface。官网上有对该接口详细介绍。如下
图1 FunctionalInterface介绍图
主要说的是,函数式接口只能有一个抽象方法,注意,声明为default不算在其中,或者Object里的public方法,即使被继承并改为abstract,也不算在其中,因为它们都是在自身或某个地方有实现的。
@FunctionalInterface
public interface testi<T> {
@SuppressWarnings("hiding")
<T> void abstractMethod(T t);
int hashCode();
}
在上面的方法中,虽然有两个抽象方法,但是,由于hashCode属于Object的public方法,因此,只算abstractMethod一个,所以testi接口会被当做一个函数式接口。
图2 符合定义的函数式接口不会弹错误提示
如果我们将hashCode改成hashCode1,由于加了FunctionalInterface注解,因此会在编译时就发现这个错误,并弹出提示。testi接口不是一个函数式接口
图3 不符合定义的函数式接口弹错误提示
对于符合函数式接口定义的接口,加不加FunctionalInterface注解都可以,但是加了之后,会在编译时就提前检查,能提前发现错误,因此官网时推荐添加该注解的。
那么为什么要提供这个函数式接口呢?理由是函数接口的实例可以用lambda表达式、方法引用或构造函数引用创建
在介绍lamada表达式之前,需要先介绍下匿名内部类,因为lamada表达式通常被用作简化创建匿名内部类。
public class CollectionTest {
@FunctionalInterface
public interface testi<T> {
@SuppressWarnings("hiding")
<T> void abstractMethod(T t);
int hashCode();
}
public static void main(String[] args) throws IOException {
Integer[] integers=new Integer[] {
1,3,4,5,5,67,8,8,6};
//传统方式,匿名内部类
for(Integer i:integers) {
new testi<Object>() {
@Override
public void abstractMethod(Object t) {
System.out.println(t);
}
}.abstractMethod(i);
}
}
}
如上所示
new testi<Object>() {
@Override
public void abstractMethod(Object t) {
System.out.println(t);
}
}.abstractMethod(i);
该匿名内部类的意思是,创建一个实例,并重写父类抽象方法,并在创建完成后调用该方法,结果如下。
图4 传统匿名内部类输出
将其改为lamada表达式后,代码如下
public class CollectionTest {
@FunctionalInterface
public interface testi<T> {
@SuppressWarnings("hiding")
<T> void abstractMethod(T t);
int hashCode();
}
public static void main(String[] args) throws IOException {
fun((x) -> System.out.println("Hello World " + x));
}
@SuppressWarnings({
"unchecked", "rawtypes" })
static void fun(testi t) {
Integer[] integers=new Integer[] {
1,3,4,5,5,67,8,8,6};
for(Integer i:integers)
t.abstractMethod(i);
}
}
在上述代码中
(x) -> System.out.println("Hello World " + x)
的本质是创建一个匿名内部类,其中右边部分为重写方法
System.out.println("Hello World " + x)
而左边是传入的参数,也就是在方法体中能被使用到,结果如下。
图5 lamada表达式输出
关于更多的lamada表达式,请参考 JDK8的新特性——Lambda表达式
但是注意,这篇博客有个解释得不怎么好的地方
图6 该博客解释不准确的点
详情请参考上述的官方解释
关于lamada表达式的更多用法,请参考 Lambda表达式更多用法