lambda 表达式 (3)-shawn,挑战大厂重燃激情
函数式接口,从字面意思上来说就是适用于函数式编程场景的接口,在 java 中函数式接口就是有且仅有一个抽象方法的接口。java 中函数式编程最主要体现就是 lambda 表达式,所以一个接口有且仅有一个抽象方法时候才能够使用 lambda 对该接口实现进行推导。
2.1 函数式接口格式
接口中有且仅有一个抽象方法:
修饰符 interface 接口名称 {public abstract 返回值类型 方法名称(可选参数信息);// 其他非抽象方法内容}
由于接口中的 public abstract 这些关键字都可以省略,所以上述函数式接口可以写成如下的形式:
修饰符 interface 接口名称 {返回值类型 方法名称(可选参数信息);// 其他非抽象方法内容}
抽象方法定义:没有方法体(没有大括号)的方法,抽象方法必须使用 abstract 修饰,在 JDK1.8 以前接口中所有方法都是没有方法体且是 public,所以 JDK1.8 以前的方法都不会写 public 和 abstract 关键字。
2.2 @FunctionalInterface 注解
如果我们定义一个接口为函数式接口,那么必须保证只有一个抽象方法。此时如果该接口被其他人添加了一个新的方法(一般是抽象方法),这就打破了原来函数式接口的设计初衷会导致程序运行过程中的问题。
针对这种情况 java 中专门为函数式接口引入了一个新的注解 @FuntionalInterface,这意味着如果一个接口被加上了@FunctionalInterface
注解且接口中有多个抽象方法那么编译的时候会报错,这就防止了函数式接口被篡改的可能。
比如如下代码由于有两个抽象方法method1();method2()
是编译不过的:
@FunctionalInterfacepublic interface MyFunctionalInterface{void method1();void method2();}
2.3 自定义一个函数式接口
我们现在自定义个一个函数式接口,为了该函数式接口不被破坏一般在函数式接口上加上@FunctionalInterface
注解。
@FunctionalInterfacepublic interface MyFunctionInterface {void method1();}
/**
测试执行函数式接口*/public class DemoMyFunctionalInterface {private static void execFunctionMethod(MyFunctionInterface inter) {inter.method1();}
public static void
main(String[] args) {execFunctionMethod(() -> {System.out.println("执行函数式接口方法!");});}}
上述代码执行结果为:执行函数式接口方法!
,再次强调@FunctionalInterface
注解可以去掉但是建议定义函数式接口都加上该注解。
3.常用函数式接口
JDK 中提供了大量常用的函数式接口,它们主要在java.util.function
包中,下面我们演示几个常用的函数式接口。
Supplier 接口
Supplier
接口在 JDK 中定义如下:
@FunctionalInterfacepublic interface Supplier<T> {
/**
Gets a result.
@return a result*/T get();}
java.util.function.Supplier
接口仅包含一个无参的方法T get()
,如果调用该方法会返回一个泛型为 T 的对象,至于对象具体如何产生由对应的 lambda 表达式提供。
我们来做一个使用 Supplier 接口从整数数组中获取最大值的例子:
public class DemoSupplier {public static int max(Supplier<Integer> sup) {return sup.get();}
public static void main(String[] args) {int arr[] = {5, 7, 338, 12};// 调用 getMax 方法,参数传递 Lambdaint maxNum = max(() -> {// 计算数组的最大值 int max = arr[0];for (int i : arr) {if (i > max) {max = i;}}return max;});System.out.println(maxNum);}}
代码执行结果为338
,其代码逻辑为定义一个方法max
参数为Supplier接口
,获取数据最大值的逻辑写在 lambda 表达式里。
评论