Java 8 Functional Interfaces – 什么时候/在哪里使用?
函数式接口,lambda 表达式和 Stream API – Java 8的这三个功能将Java编程变成了一种称为函数式编程的新型编程样式。 Java仍然是一种面向对象的编程语言,但是从Java 8开始,随着新功能的引入,大多数编程都是在考虑功能而不是对象的情况下完成的。 在本文中,我们将看到 Java 8 函数式接口 @FunctionalInterface 注解,java.util.function包,以及如何通过一些简单的示例使用新的 Java 8 函数式接口来组成 lambda 表达式。
一、定义
函数式接口是只有一种抽象方法的接口。 它们可以具有任意数量的默认方法,但必须仅具有一个抽象方法。函数式接口仅提供一种要实现的函数功能。
Java 8之前存在函数式接口。并不是说它们只是Java 8中引入的全新概念。Runnable
,ActionListener,
Callable和
Comaprator` 是一些旧的函数式接口,甚至在Java 8之前就已经存在。
Java 8 中引入了新的函数式接口集,以使程序员在编写 lambda 表达式时的工作变得容易。 您的 lambda 表达式必须实现这些函数式接口中的任何一个。 这些新的函数式接口在java.util.function 包下进行组织。
二、@FunctionalInterface 注解
Java 8中引入了@FunctionalInterface
注释,以表示函数式接口。 虽然,使用此注释编写函数式接口不是强制性的。 但是,如果使用 @FunctionalInterface
批注,则您的接口应仅包含一个抽象方法。 如果尝试编写多个抽象方法,则编译器将显示错误。
三、java.util.function package
所有Java 8 函数式接口都组织在 java.util.function 包中。 此程序包中的每个函数式接口都表示可以由 lambda 表达式执行的操作。
下表显示了所有 Java 8 函数式接口及其抽象方法的列表,它们代表的操作以及何时使用它们?
函数式接口 | 抽象方法 | 操作符含义 | 什么时候用? | 支持基础类型的相关函数式接口 |
---|---|---|---|---|
Predicate | boolean test(T t) | T -> boolean | 传入参数 T 的布尔表达式 | IntPredicate LongPredicate DoublePredicate |
Consumer | void accept(T t) | T -> void | 消费一个对象,执行一些操作 | IntConsumer LongConsumer DoubleConsumer |
Function | R apply(T t) | T -> R | 从现存 T 中做运算得到 R | IntFunction LongFunction DoubleFunction toIntFunction toLongFunction toDoubleFunction IntToLongFunction IntToDoubleFunction LongToDoubleFunction LongToIntFunction DoubleToIntFunction DoubleToLongFunction |
Supplier | T get() | void -> T | 创建一个新对象 T | |
BiPredicate | boolean test(T t, U u) | Predicate 两个参数 | 传入两个参数的布尔表达式 | |
BiConsumer | void accept(T t, U u) | (T, U) -> void | 同时消费两个对象 | |
BiFunction | R apply(T t, U u) | (T, U) -> R | 从现存两个对象 T 和 U 中做运算得到 R | ObjIntConsumer ObjLongConsumer ObjDoubleConsumer |
UnaryOperator | (extends Function) | 入参与返参同样类型的 Function | 和 Function 功能一样 | IntUnaryOperator LongUnaryOperator DoubleUnaryOperator |
BinaryOperator | (extends BiFunction) | 入参与返参同样类型的 Function | 和 BiFunction 功能一样 | IntBinaryOperator LongBinaryOperator DoubleBinaryOperator |
四、如何使用函数式接口
下面定义一个 Student
类在后续示例中,我们将使用此类。
class Student
{
int id;
String name;
double percentage;
String specialization;
public Student(int id, String name, double percentage, String specialization)
{
this