JDK1.8提供一种特殊的接口 -- 函数式接口(Functional Interface),它与普通接口相比,就是比普通的接口多了一个方法。 函数式接口可以被隐式转换为lambda表达式。函数式接口现有的函数可以友好地支持 lambda。
其实早在JDK 1.8之前就已经有了一些函数式接口,如下:
JDK 1.8 版本新增加的函数接口:
java.util.function 可以用来支持 Java的 函数式编程,该包中的函数式接口有:
序号 | 接口 & 描述 |
---|---|
1 | BiConsumer<T,U>代表了一个接受两个输入参数的操作,并且不返回任何结果 |
2 | BiFunction<T,U,R>代表了一个接受两个输入参数的方法,并且返回一个结果 |
3 | BinaryOperator<T>代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果 |
4 | BiPredicate<T,U>代表了一个两个参数的boolean值方法 |
5 | BooleanSupplier代表了boolean值结果的提供方 |
6 | Consumer<T>代表了接受一个输入参数并且无返回的操作 |
7 | DoubleBinaryOperator代表了作用于两个double值操作符的操作,并且返回了一个double值的结果。 |
8 | DoubleConsumer代表一个接受double值参数的操作,并且不返回结果。 |
9 | DoubleFunction<R>代表接受一个double值参数的方法,并且返回结果 |
10 | DoublePredicate代表一个拥有double值参数的boolean值方法 |
11 | DoubleSupplier代表一个double值结构的提供方 |
12 | DoubleToIntFunction接受一个double类型输入,返回一个int类型结果。 |
13 | DoubleToLongFunction接受一个double类型输入,返回一个long类型结果 |
14 | DoubleUnaryOperator接受一个参数同为类型double,返回值类型也为double 。 |
15 | Function<T,R> 接受一个输入参数,返回一个结果。 |
16 | IntBinaryOperator接受两个参数同为类型int,返回值类型也为int 。 |
17 | IntConsumer接受一个int类型的输入参数,无返回值 。 |
18 | IntFunction<R>接受一个int类型输入参数,返回一个结果 。 |
19 | IntPredicate:接受一个int输入参数,返回一个布尔值的结果。 |
20 | IntSupplier无参数,返回一个int类型结果。 |
21 | IntToDoubleFunction接受一个int类型输入,返回一个double类型结果 。 |
22 | IntToLongFunction接受一个int类型输入,返回一个long类型结果。 |
23 | IntUnaryOperator接受一个参数同为类型int,返回值类型也为int 。 |
24 | LongBinaryOperator接受两个参数同为类型long,返回值类型也为long。 |
25 | LongConsumer接受一个long类型的输入参数,无返回值。 |
26 | LongFunction<R>接受一个long类型输入参数,返回一个结果。 |
Predicate <T> 接口是一个函数式接口,它接受一个输入参数 T,返回一个布尔值结果。
该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)。
该接口用于测试对象是 true 或 false。
我们可以通过以下实例(Java8FunctionTest.java)来了解函数式接口 Predicate <T> 的使用:
package com.wenxue.jdk8;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/**
* @className: FunctionTest
* @Description: TODO 测试java1.8的函数式接口
* @version: v1.9.3
* @author: GONGWENXUE
* @date: 2019/12/11 15:39
*/
public class Java8FunctionTest {
/**
* @Author GONGWENXUE
* @Description //TODO 测试 Predicate<T>函数式接口,传入一个参数n,返回一个boolean结果。
* @version: v1.9.3
* @Date 15:50 2019/12/11
* @Param
* @return
**/
public static void testFun(List<Integer> list, Predicate<Integer> predicate) {
for(Integer n: list) {
//当真正执行函数接口对象的test(n)时,才具体的传入了n的值。
// 前面的表达式( n-> n%2 == 0)是函数式接口test方法的实现逻辑。
if(predicate.test(n)) {
System.out.println(n + " ");
}
}
}
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
System.out.println("输出所有偶数:");
// Predicate<Integer> predicate1 = n -> 运算表达式(n%2==0)
// n 是传递到 Predicate 接口的 test 方法的一个参数
// n%2==0:是test方法的实现逻辑,这里是使用Lam表达式实现了对象的创建与抽象方法的实现
// 调用方法传入n-> n%2 == 0时就已经实现了函数接口的对象与test方法的重写
// 然后调用test方法,test方法的重写逻辑,从而返回ture或者false
// n-> n%2 == 0: 标识函数式接口的test方法需要按照“参数值是偶数”时才返回true.
testFun(list, n-> n%2 == 0 );//2,4,6
System.out.println("输出大于 3 的所有数字:");
testFun(list, n-> n > 3 );//4,5,6
}
}
1.先编写函数式接口:
package com.wenxue.jdk8;
/**
* @className: MyFunctionalInterface
* @Description: TODO 自定义函数式接口
* @version: v1.9.3
* @author: GONGWENXUE
* @date: 2019/12/11 21:14
*/
@FunctionalInterface
public interface MyFunctionalInterface<T> {
Integer test(T t, T t2);
//函数式接口有且只有一个抽象方法,写多个时@FunctionalInterface会报错
//Integer test2(T t, T t2);
}
2.创建接口对象,实现抽象方法:
MyFunctionalInterface<Integer> myFunctionalInterface = (n,n2) -> n + n2;
3.调用函数接口方法:
package com.wenxue.jdk8;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/**
* @className: FunctionTest
* @Description: TODO 测试java1.8的函数式接口
* @version: v1.9.3
* @author: GONGWENXUE
* @date: 2019/12/11 15:39
*/
public class Java8FunctionTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
//创建函数式接口对象, 实现test方法的逻辑为将两个参数相加后返回
MyFunctionalInterface<Integer> myFunctionalInterface = (n,n2) -> n + n2;
//调用函数式接口方法,执行运算逻辑
testMyFunctionalInterface(list, myFunctionalInterface);
}
public static void testMyFunctionalInterface(List<Integer> list, MyFunctionalInterface<Integer> myFunctionalInterface) {
for(Integer n: list) {
Integer result = myFunctionalInterface.test(n,n);
System.out.println(result);//2,4,6
}
}
}
@FunctionalInterface
public interface MyFunctionalInterface<T> {
Integer test(T t, T t2);
//函数式接口有且只有一个抽象方法,写多个会报错
//Integer test2(T t, T t2);
@Override//这个equals方法是从Object继承下来的,这里只是表示重写,所以不算多余的额外的抽象接口
boolean equals(Object obj);
}