最近在复习java基础知识,发现了一个面试题:
java中的函数式接口是什么?
老实说,我一开始看到“函数式接口”这个术语,愣了一下:
java中的函数式接口是什么?我在平时的项目开发中是否用过呢?
从网上查阅了一下资料才发现:原来就是jdk1.8的新特性之一-Lambda表达式!!!!!!
可以肯定的是,项目开发中肯定是用到了,例如:
使用 Runnable匿名内部类的方式去创建Thread对象、Stream流式编程的forEach等方法、集合的sort方法等等......
此时就可以使用lambda表达式来简化代码了。
只是我并没有去深入研究过底层的实现原理;所以我结合了个人理解和实践总结一下这一块的知识,特此记录。
答:简单地说就是,如果一个interface类有且只有一个abstract方法,那这个接口类就是函数式接口。对于函数式接口,在调用其方法时可以通过Lambda表达式来简化代码。
条件:interface 有且仅有一个抽象方法(注意:interface 接口类中所有不带方法体的方法默认都是带abstract修饰的,即抽象方法,但是interface接口类中可以定义带方法体的default方法,这就不是abstract方法)。
答:在interface接口类上使用类注解@FunctionalInterface来修饰,可以显式的得知一个interface接口类是否为函数式接口:如果注解报错就不是函数式接口,不报错则是函数式接口。
注意:@FunctionalInterface是显式方法,实际上jit编译器会隐式判断,所以实际使用时不需要加上该注解。
如:



可以看到:
当只存在一个方法时,@FunctionalInterface注解没有报错。此时就是函数式接口。
当存在default方法时,由于它不是抽象方法,所以依旧是函数式接口。
当存在2个抽象方法时,注解会报错(报红)!表明此时就不再是函数式接口了。

使用lambda表达式简化后:

答:除了自定义函数式接口之外,jdk8中官方还在java.util.function包给定了许多函数式接口,如:
1、Supplier生产型接口:有且仅有一个无参的、返回值为Object的get方法。

使用:

lambda简化后:

2、Consumer消费型接口:一个带参的、无返回值的抽象方法accept;和一个default默认方法andThen。
使用:

可以看出andThen方法的作用就是控制2个Consumer的顺序,一般会和后面的accept方法一起使用,accept方法的传参会同时作用于2个Consumer,因此最终就是调用Consumer1的accept()方法再调用Consumer2的accept()方法。
3、Predicate接口:常用于判断参数是否满足指定的条件。带有4个方法:
boolean test(T t):抽象方法。返回一个布尔值,常用于对传入的参数进行某个条件判断)。
default Predicate
default Predicate
default Predicate
static Predicate
使用:

4、Function接口:
R apply(T t):将此函数应用于给定的参数。
default
Function

使用:
