在上一篇中咱们已经介绍了什么是功能接口以及Jdk中java.util.function
下的Function的基础用法。java
下面咱们将会介绍高阶函数,什么是高阶函数呢?就是能够定义任意同类计算的函数。 下面看个例子:bash
public class Demo{
public static void main(String[] args){
Function<Integer,Function<Integer,Integer>> m1 = a -> b -> a+b;
Function<Integer,Integer> func = m1.apply(1);
Integer x = 2;
System.out.println("m1计算结果"+func.apply(x));//输出3
Function<Integer,Integer> func2 = m1.apply(5);
System.out.println("m1计算结果2:"+func2.apply(x));//输出7
}
}
复制代码
下面来简单解释一下,上面代码中的m1是一个Function,其自己的返回值仍是一个Function,就是说,m1返回值用lambda表达式就是b->a+b
。所以下面的就很容易了。app
BiFunction是是一个二元函数的接口声明,所谓二元就是支持两个参数。上面咱们看到的Function只接受一个参数。这就是二者之间的区别。less
public static void mian(String[] args){
Bifunction<Integer,Integer,Integer> func = (x,y) -> x+b;
System.out.println("x+y="+func.apply(2,3));//输出5
}
复制代码
须要注意的是,这个二元函数的default方法只有一个andThen
方法,没有compose
方法。ide
下面列出Function相关的接口:函数
BiFunction :R apply(T t, U u);接受两个参数,返回一个值,表明一个二元函数
DoubleFunction :R apply(double value);只处理double类型的一元函数
IntFunction :R apply(int value);只处理int参数的一元函数
LongFunction :R apply(long value);只处理long参数的一元函数
ToDoubleFunction:double applyAsDouble(T value);返回double的一元函数
ToDoubleBiFunction:double applyAsDouble(T t, U u);返回double的二元函数
ToIntFunction:int applyAsInt(T value);返回int的一元函数
ToIntBiFunction:int applyAsInt(T t, U u);返回int的二元函数
ToLongFunction:long applyAsLong(T value);返回long的一元函数
ToLongBiFunction:long applyAsLong(T t, U u);返回long的二元函数
DoubleToIntFunction:int applyAsInt(double value);接受double返回int的一元函数
DoubleToLongFunction:long applyAsLong(double value);接受double返回long的一元函数
IntToDoubleFunction:double applyAsDouble(int value);接受int返回double的一元函数
IntToLongFunction:long applyAsLong(int value);接受int返回long的一元函数
LongToDoubleFunction:double applyAsDouble(long value);接受long返回double的一元函数
LongToIntFunction:int applyAsInt(long value);接受long返回int的一元函数
复制代码
Operatorui
包括UnaryOperator
和BinaryOperator
。分别对应单元算子和二元算子this
UnaryOperator:lua
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
/**
* Returns a unary operator that always returns its input argument.
*
* @param <T> the type of the input and output of the operator
* @return a unary operator that always returns its input argument
*/
static <T> UnaryOperator<T> identity() {
return t -> t;
}
}
复制代码
BinaryOperator:spa
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
/**
* Returns a {@link BinaryOperator} which returns the lesser of two elements
* according to the specified {@code Comparator}.
*
* @param <T> the type of the input arguments of the comparator
* @param comparator a {@code Comparator} for comparing the two values
* @return a {@code BinaryOperator} which returns the lesser of its operands,
* according to the supplied {@code Comparator}
* @throws NullPointerException if the argument is null
*/
public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
/**
* Returns a {@link BinaryOperator} which returns the greater of two elements
* according to the specified {@code Comparator}.
*
* @param <T> the type of the input arguments of the comparator
* @param comparator a {@code Comparator} for comparing the two values
* @return a {@code BinaryOperator} which returns the greater of its operands,
* according to the supplied {@code Comparator}
* @throws NullPointerException if the argument is null
*/
public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
}
复制代码
算子就是一个针对同类型输入输出的一个映射。在此接口下,只需声明一个泛型参数T便可。对应上面的例子:
public static void main(String[] args){
UnaryOperator<Integer> addFunc = x -> x+1;
System.out.println("addFunc:"+addFunc.apply(2));//输出3
BinaryOperator<Integer> addFunc2 = (x,y) -> x+y;
System.out.println("addFunc2:"+addFunc2.apply(2,3));//5
//minBy方法传入一个Comparator接口的函数用做比较两个数大小的规则
BinaryOperator<Integer> min = BinaryOperator.minBy((a,b) -> a-b);
System.out.println(min.apply(5,9));//5
BinaryOperator<Integer> max = BinaryOperator.maxBy((a,b) -> a-b);
System.out.println(max.apply(5,9));//9
}
复制代码
还有就是其余的一下基础的扩展算子,一看就知道什么意思就不细说了。
LongUnaryOperator:long applyAsLong(long operand);
IntUnaryOperator:int applyAsInt(int operand);
DoubleUnaryOperator:double applyAsDouble(double operand);
DoubleBinaryOperator:double applyAsDouble(double left, double right);
IntBinaryOperator:int applyAsInt(int left, int right);
LongBinaryOperator:long applyAsLong(long left, long right);
复制代码
Predicate
Predicate是谓词函数,很明显了,所谓谓词,就是返回值为Boolean类型的函数。其抽象方法是一个test
,下面是源码:
/**
* 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);
复制代码
默认方法有and
、or
和negate
,分别对应代码中的&&
、||
和!
,很简单,就不举例子了。
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);
}
复制代码
Predicate的其余接口函数:
BiPredicate:boolean test(T t, U u);接受两个参数的二元谓词
DoublePredicate:boolean test(double value);入参为double的谓词函数
IntPredicate:boolean test(int value);入参为int的谓词函数
LongPredicate:boolean test(long value);入参为long的谓词函数
复制代码
Consumer
见文知意,消费者,确定就是消费掉了,没有返回结果喽~
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
复制代码
这也就说明,在咱们平时的代码中全部的无返回值类型,且一个参数的实体方法都是这个函数接口的“映射”啦,哈哈,还记得前面说的“映射”是什么意思吗? 这个也很简单,例子就不写了。
看看其余的一些Consumer:
BiConsumer:void accept(T t, U u);接受两个参数
DoubleConsumer:void accept(double value);接受一个double参数
IntConsumer:void accept(int value);接受一个int参数
LongConsumer:void accept(long value);接受一个long参数
ObjDoubleConsumer:void accept(T t, double value);接受一个泛型参数一个double参数
ObjIntConsumer:void accept(T t, int value);接受一个泛型参数一个int参数
ObjLongConsumer:void accept(T t, long value);接受一个泛型参数一个long参数
复制代码
Supplier
有了上边的消费者,那确定也就有生产者了,既然是生产者,那确定就是不须要参数,本身生产东西并返回喽~
/**
* Gets a result.
*
* @return a result
*/
T get();
复制代码
只有一个无参get
方法,并返回T
类型。没有提供其余默认方法。看其余的博客中有的人说这个函数接口不是为了说明一个参数空间到结果空间的映射,而是要表达一种生产能力。细想我我的以为说的也蛮好。能够想象咱们用过的工厂方法。
其余的一些Supplier:
BooleanSupplier:boolean getAsBoolean();返回boolean
DoubleSupplier:double getAsDouble();返回double
IntSupplier:int getAsInt();返回int
LongSupplier:long getAsLong();返回long
复制代码
以上就是我对这些函数式接口的大概介绍,有什么不对的还望指正,谢谢。