前面两篇文章分别介绍了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);
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!