什么是函数式式(Functional)
- 只包含一个抽象方法的接口,称为函数式接口
- 你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)。
- 我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。
- 在java.util.function包下定义了Java 8 的丰富的函数式接口
如何理解函数式接口
- Java从诞生日起就是一直倡导“一切皆对象”,在Java里面面向对象(OOP)编程是一切。但是随着python、scala等语言的兴起和新技术的挑战,Java不得不做出调整以便支持更加广泛的技术要求,也即java不但可以支持OOP还可以支持OOF(面向函数编程)
- 在函数式编程语言当中,函数被当做一等公民对待。在将函数作为一等公民的编程语言中,Lambda表达式的类型是函数。但是在Java8中,有所不同。在Java8中,Lambda表达式是对象,而不是函数,它们必须依附于一类特别的对象类型——函数式接口。
- 简单的说,在Java8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也就是说,只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示。
- 所以以前用匿名实现类表示的现在都可以用Lambda表达式来写.
函数式接口举例
自定义函数式接口
@FunctionalInterface
public interface MyNumber{
public double getValue();
}
函数式接口中使用泛型:
@FunctionalInterface
public interface MyFunc<T>{
public T getValue(T t);
}
作为递 参数传递 Lambda
作为参数传递 Lambda 表达式:为了将 Lambda 表达式作为参数传递,接收Lambda该 表达式的参数类型必须是与该 Lambda 表达式兼容的函数式接口的类型。
Java 内置四大核心函数式接口
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer<T>消费型接口 | T | void | 对类型为T的对象应用操作,包含方法:void accept(T t) |
Supplier<T>供给型接口 | 无 | T | 返回类型为T的对象,包含方法:T get() |
Function<T, R>函数型接口 | T | R | 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t) |
Predicate<T>断定型接口 | T | boolean | 确定类型为T的对象是否满足某约束,并返回boolean 值。包含方法:boolean test(T t) |
其他接口
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
BiFunction<T, U, R> | T, U | R | 对类型为 T, U 参数应用操作,返回 R 类型的结果。包含方法为: R apply(T t, U u); |
UnaryOperator<T>(Function 子接口) | T | T | 对类型为T的对象进行一元运算,并返回T类型的结果。包含方法为:T apply(T t); |
BinaryOperator<T>(BiFunction 子接口) | T, T | T | 对类型为T的对象进行二元运算,并返回T类型的结果。包含方法为: T apply(T t1, T t2); |
BiConsumer<T, U> | T, U | void | 对类型为T, U 参数应用操作。包含方法为: void accept(T t, U u) |
BiPredicate<T,U> | T,U | boolean | 包含方法为: boolean test(T t,U u) |
ToIntFunction<T> ToLongFunction<T> ToDoubleFunction<T> | T | int long double | 分别计算int、long、double值的函数 |
IntFunction<R> LongFunction<R> DoubleFunction<R> | int long double | R | 参数分别为int、long、double 类型的函数 |