前面两篇文章分别介绍了lambda表达式的基础用法和进阶用法,而在java中lambda表达式使用需要依赖于函数式接口。那么什么是函数式接口,我们又怎么自定义一个函数式接口,JDK中有哪些函数式接口?上述问题我们会在今天这篇文章中详细解答。
2. 什么是函数接口
函数式接口,从字面意思上来说就是适用于函数式编程场景的接口,在 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()
是编译不过的:
@FunctionalInterface
public interface MyFunctionalInterface
{
void method1();
void method2();
}
2.3 自定义一个函数式接口
我们现在自定义个一个函数式接口,为了该函数式接口不被破坏一般在函数式接口上加上@FunctionalInterface
注解。
@FunctionalInterface
public 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中定义如下:
@FunctionalInterface
public interface Supplier {
/**
- 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 sup) {
return sup.get();
}
public static void main(String[] args) {
int arr[] = {5, 7, 338, 12};
// 调用getMax方法,参数传递Lambda
int 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表达式里。
Consumer接口
Consumer
接口在JDK中定义如下:
@FunctionalInterface
public interface Consumer {
/**
- Performs this operation on the given argument.
- @param t the input argument
*/
void accept(T t);
最后
**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
972219)]
[外链图片转存中…(img-tGkgx44u-1715672972221)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!