熟悉JS的同学都知道在JS中,函数可以作为参数也可以作为返回值使用,这种编程方式就是函数式编程。而在Java 7及以前的版本中,是缺少这种支持的。
在函数式编程思想下,允许把函数本身作为参数传入另一个函数,在Java 8中实现了函数式编程,通过使用函数式接口来“传递行为”的方式实现了这种函数式编程思想。
当然也也依赖了JDK8中方法引用、Lambda表达式等新特性的支持。
函数式接口
通过@FunctionalInterface
注解进行标识,一个函数式接口需要满足两个条件:
- 必须是接口;
- 只有一个抽象方法(接口中的默认方法、静态方法都不算抽象方法);
其实满足上述两个条件的接口及时不添加@FunctionalInterface
注解,也可以作为函数式接口来使用的。
通过上述的两个条件很容易理解,函数式接口在使用时,就是将lambda表达式中的方法体或者方法引用等来替代唯一的抽象方法,因为抽象方法唯一,所以对方法的名称不敏感,可以随意定义方法名(方法引用)或者没有方法名(lambda表达式形式),但方法签名必须一致。
JDK为了规范函数式接口的开发,也为了为函数式编程提供便利,提供了很多常用的函数式接口实现,这些实现的区别主要在于抽象方法的签名,如接收的参数个数、参数类型、返回值类型等。

以下的接口代码省略了非抽象方法
Supplier<T>
顾名思义,就是一个提供者接口,其中只有一个抽象方法get(),无参数,返回一个对象。Supplier函数式接口为“提供给定类型对象”的行为提供了一种抽象。
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
Consumer<T>
顾名思义,就是一个消费者接口,其中只有一个accept抽象方法,接受一个参数,没有返回值。实际编译后是通过LambdaMetafactory调用的Consumer的accept方法,而accept方法又是通过lambda表达式中的方法体实现的。
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
}
Consumer函数式接口为“消费给定对象”的行为提供了抽象,通过该函数式接口的accept方法可实现自定义的消费行为。
Function<T,R>
是一个函数接口,只有一个apply抽象方法,接受一个参数产生一个返回值。
Function函数式接口接受一个T类型的参数,返回一个R类型的结果。该函数式接口是对有一个输入参数,产生一个输出结果的一类函数或行为的抽象。
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
Predicate<T>
是一个预测接口,只有test方法。
Predicate函数式接口接受一个输入参数,返回boolean类型的结果。该函数式接口像特殊的Function<T,Boolean>函数式接口。
@FunctionalInterface
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
}
java.util.function包下其余接口
其余接口都是上述类型的变体,主要是参数类型、参数数量、返回值的具化。
网友评论