博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java8 函数式编程之函数接口(下)
阅读量:6376 次
发布时间:2019-06-23

本文共 6935 字,大约阅读时间需要 23 分钟。

在上一篇中我们已经介绍了什么是功能接口以及Jdk中java.util.function下的Function的基础用法。

下面我们将会介绍高阶函数,什么是高阶函数呢?就是可以定义任意同类计算的函数。 下面看个例子:

public class Demo{        public static void main(String[] args){                Function
> m1 = a -> b -> a+b; Function
func = m1.apply(1); Integer x = 2; System.out.println("m1计算结果"+func.apply(x));//输出3 Function
func2 = m1.apply(5); System.out.println("m1计算结果2:"+func2.apply(x));//输出7 }}复制代码

下面来简单解释一下,上面代码中的m1是一个Function,其本身的返回值还是一个Function,就是说,m1返回值用lambda表达式就是b->a+b。因此下面的就很容易了。

BiFunction是是一个二元函数的接口声明,所谓二元就是支持两个参数。上面我们看到的Function只接受一个参数。这就是两者之间的区别。

public static void mian(String[] args){    Bifunction
func = (x,y) -> x+b; System.out.println("x+y="+func.apply(2,3));//输出5}复制代码

需要注意的是,这个二元函数的default方法只有一个andThen方法,没有compose方法。

下面列出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的一元函数复制代码

Operator

包括UnaryOperatorBinaryOperator。分别对应单元算子和二元算子

UnaryOperator:

@FunctionalInterfacepublic interface UnaryOperator
extends Function
{ /** * Returns a unary operator that always returns its input argument. * * @param
the type of the input and output of the operator * @return a unary operator that always returns its input argument */ static
UnaryOperator
identity() { return t -> t; }}复制代码

BinaryOperator:

@FunctionalInterfacepublic interface BinaryOperator
extends BiFunction
{ /** * Returns a {@link BinaryOperator} which returns the lesser of two elements * according to the specified {@code Comparator}. * * @param
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
BinaryOperator
minBy(Comparator
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
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
BinaryOperator
maxBy(Comparator
comparator) { Objects.requireNonNull(comparator); return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; }}复制代码

算子就是一个针对同类型输入输出的一个映射。在此接口下,只需声明一个泛型参数T即可。对应上面的例子:

public static void main(String[] args){        UnaryOperator
addFunc = x -> x+1; System.out.println("addFunc:"+addFunc.apply(2));//输出3 BinaryOperator
addFunc2 = (x,y) -> x+y; System.out.println("addFunc2:"+addFunc2.apply(2,3));//5 //minBy方法传入一个Comparator接口的函数用作比较两个数大小的规则 BinaryOperator
min = BinaryOperator.minBy((a,b) -> a-b); System.out.println(min.apply(5,9));//5 BinaryOperator
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);复制代码

默认方法有andornegate,分别对应代码中的&&||!,很简单,就不举例子了。

default Predicate
and(Predicate
other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t);}default Predicate
negate() { return (t) -> !test(t);}default Predicate
or(Predicate
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();返回booleanDoubleSupplier:double getAsDouble();返回doubleIntSupplier:int getAsInt();返回intLongSupplier:long getAsLong();返回long复制代码

以上就是我对这些函数式接口的大概介绍,有什么不对的还望指正,谢谢。

转载于:https://juejin.im/post/5b77a565e51d4538a751d0a0

你可能感兴趣的文章
Hibernate学习(八):检索方式
查看>>
RIPv1 PK RIPv2
查看>>
基于WorsPress+Xampp搭建博客
查看>>
javascript的一些基本概念
查看>>
关于Tomcat上请求的编解码问题
查看>>
WPF“动画序列”框架的初步研究与实现(附源码)
查看>>
Windows Server 2008 多元密码策略配置
查看>>
.NET中的泛型和Java泛型中的类型擦除
查看>>
白利用的集大成者:新型远控木马上演移形换影大法
查看>>
2017必备的八款最佳反勒索软件工具
查看>>
从Effective Java总结一些有助安卓开发的建议
查看>>
以一当十的程序员不是传说
查看>>
Vizinex RFID 和Brady SmartID推出航空标签
查看>>
Facebook 否认趋势话题存在政治偏见,但将做出调整
查看>>
云纵发布“纵横客“ 新一代互联网CRM开启餐饮行业营销新模式
查看>>
物联网到底何时才能称为“爆发”?
查看>>
《Java多线程编程核心技术》——1.2节使用多线程
查看>>
不用惊慌 关于苹果警告的一些分析
查看>>
《VMware 网络技术:原理与实践》—— 2.3 OSI模型
查看>>
金融安全资讯精选 2017年第十五期:普华永道消费者隐私信息保护调研称69%的企业无力面对网络攻击,中小银行转型系统整合中的建议...
查看>>