JDK源码 java.util.function包下面提供的一系列的预置的函数式接口定义:
部分使用场景比较多的函数式接口的功能描述归纳如下:
接口类功能描述Runnable直接执行一段处理函数,无任何输出参数,也没有任何输出结果。Supplier执行一段处理函数,无任务输入参数,返回一个T类型的结果。与Runnable的区别在于Supplier执行完之后有返回值。Consumer执行一段处理函数,支持传入一个T类型的参数,执行完没有任何返回值。BiConsumer与Consumer类型相似,区别点在于BiConsumer支持传入两个不同类型的参数,执行完成之后依旧没有任何返回值。Function执行一段处理函数,支持传入一个T类型的参数,执行完成之后,返回一个R类型的结果。与Consumer的区别点就在于Function执行完成之后有输出值。BiFunction与Function相似,区别点在于BiFunction可以传入两个不同类型的参数,执行之后可以返回一个结果。与BiConsumer也很类似,区别点在于BiFunction可以有返回值。UnaryOperator传入一个参数对象T,允许对此参数进行处理,处理完成后返回同样类型的结果对象T。继承Function接口实现,输入输出对象的类型相同。BinaryOperator允许传入2个相同类型的参数,可以对参数进行处理,最后返回一个仍是相同类型的结果T。继承BiFunction接口实现,两个输入参数以及最终输出结果的对象类型都相同。Predicate支持传入一个T类型的参数,执行一段处理函数,最后返回一个布尔类型的结果。BiPredicate支持传入2个相同类型T的参数,执行一段处理函数,最后返回一个布尔类型的结果。JDK中 java.util.function 包内预置了这么多的函数式接口,很多场景下其实都是给JDK中其它的类或者方法中使用的,最典型的就是Stream了——可以说有一大半预置的函数式接口类,都是为适配Stream相关能力而提供的。也正是基于函数式接口的配合使用,才是使得Stream的灵活性与扩展性尤其的突出。
下面我们一起来看几个Stream的方法实现源码,来感受下函数式接口使用的魅力。
比如,Stream中的 filter过滤操作,其实就是传入一个元素对象,然后经过一系列的处理与判断逻辑,最后需要给定一个boolean的结果,告知filter操作是应该保留还是丢弃此元素,所以filter方法传入的参数就是一个 Predicate函数式接口的具体实现(因为Predicate接口的特点就是传入一个T对象,输出一个boolean结果):
[code]/*** Returns a stream consisting of the elements of this stream that match* the given predicate.*/ Stream filter(Predicate