所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。
1.1 函数式接口里允许定义默认方法:
函数式接口里是可以包含默认方法,因为默认方法不是抽象方法,其有一个默认实现,所以是符合函数式接口的定义的;
1.2 函数式接口里允许定义静态方法:
函数式接口里是可以包含静态方法,因为静态方法不能是抽象方法,是一个已经实现了的方法,所以是符合函数式接口的定义的;
1.3 函数式接口里允许定义java.lang.Object里的public方法:
函数式接口里是可以包含Object里的public方法,这些方法对于函数式接口来说,不被当成是抽象方法(虽然它们是抽象方法);因为任何一个函数式接口的实现,默认都继承了Object类,包含了来自java.lang.Object里对这些抽象方法的实现;
1.4 函数式接口里允许子接口继承多个父接口,但每个父接口中都只能存在一个抽象方法,且必须的相同的抽象方法。
下面给出几个函数式接口的例子:
@FunctionalInterface public interface Predicate<T> { boolean test(T t); default Predicate<T> and(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } default Predicate<T> negate() { return (t) -> !test(t); } default Predicate<T> or(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } static <T> Predicate<T> isEqual(Object targetRef) { return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object); }
@FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); …………
@FunctionalInterface public interface A<T> extends Predicate, MyPredicate { /** * 1. * 父接口 MyPredicate与 Predicate中存在相同的抽象方法:boolean test(T t); * 因此子接口中的功能也只有 boolean test(T t); */ /** * 2. * 如果多个父接口有各自不同的抽象方法,则子接口也会存在继承多个抽象方法 * 此时,子接口就不是函数式接口 */ }
2.@FunctionalInterface注解
Java 8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。加不加@FunctionalInterface对于接口是不是函数式接口没有影响,该注解只是提醒编译器去检查该接口是否仅包含一个抽象方法。
3.函数式接口的运用3.1 函数式接口也是接口,依旧可以通过之前的调用方式,通过实现类来使用接口。
public class FunctionalInterfaceTest<T> implements Predicate<T>{ public static void main(String[] args) throws InterruptedException { Predicate p = new FunctionalInterfaceTest(); System.out.println(p.test(1)); } @Override public boolean test(T t) { return 1 % 2 == 0; } }
3.2 通过Lambda表达式实现接口抽象方法
public static void main(String[] args) throws InterruptedException { Predicate<Integer> p = a -> a % 2 == 1; System.out.println(p.test(5)); System.out.println(p.test(2)); }
3.3 函数式接口与之前编码的比较
/** * java 8 之前通常使用匿名内部类完成 */ Collections.sort(dtoList, new Comparator<PlatformCouponOrderDTO>() { @Override public int compare(PlatformCouponOrderDTO a, PlatformCouponOrderDTO b) { return DateUtils.getMinutesBetween(a.getTime(), b.getTime()); } }); /** * java 8 之后使用Lambda表达式实现函数式接口,使代码量明显减少许多 */ Collections.sort(dtoList, (a, b) -> DateUtils.getMinutesBetween(a.getTime(), b.getTime()));
4.JDK 1.8 新增加的函数接口:
- java.util.function
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类型输入参数,返回一个结果。 |
27 |
LongPredicate
R接受一个long输入参数,返回一个布尔值类型结果。 |
28 |
LongSupplier
无参数,返回一个结果long类型的值。 |
29 |
LongToDoubleFunction
接受一个long类型输入,返回一个double类型结果。 |
30 |
LongToIntFunction
接受一个long类型输入,返回一个int类型结果。 |
31 |
LongUnaryOperator
接受一个参数同为类型long,返回值类型也为long。 |
32 |
ObjDoubleConsumer<T>
接受一个object类型和一个double类型的输入参数,无返回值。 |
33 |
ObjIntConsumer<T>
接受一个object类型和一个int类型的输入参数,无返回值。 |
34 |
ObjLongConsumer<T>
接受一个object类型和一个long类型的输入参数,无返回值。 |
35 |
Predicate<T>
接受一个输入参数,返回一个布尔值结果。 |
36 |
Supplier<T>
无参数,返回一个结果。 |
37 |
ToDoubleBiFunction<T,U>
接受两个输入参数,返回一个double类型结果 |
38 |
ToDoubleFunction<T>
接受一个输入参数,返回一个double类型结果 |
39 |
ToIntBiFunction<T,U>
接受两个输入参数,返回一个int类型结果。 |
40 |
ToIntFunction<T>
接受一个输入参数,返回一个int类型结果。 |
41 |
ToLongBiFunction<T,U>
接受两个输入参数,返回一个long类型结果。 |
42 |
ToLongFunction<T>
接受一个输入参数,返回一个long类型结果。 |
43 |
UnaryOperator<T>
接受一个参数为类型T,返回值类型也为T。 |