您的位置:首页 > 编程语言 > Java开发

java8学习之Supplier与函数式接口总结

2018-01-08 17:42 423 查看
[b]Supplier接口:[/b]

继续学习一个新的函数式接口--Supplier,它的中文意思为供应商、提供者,下面看一下它的javadoc:







而具体的方法也是相当的简单,就是不接受任何参数,返回一个结果:



对它有了大概的了解之后,下面用代码来使用一下它:



貌似这函数的使用相当简单呀,但是简单并非是它的用处少,那它到底可以应用在现实中的什么场合之下呢?工厂就是其一,因为工厂有时里面是不接收参数的,直接从工厂里面返回一个结果,当然如果工厂里面要接收参数且返回结果那Function函数式接口就可以派上用场了,下面还是看一下这种Supplier的场景:

首先定义一个实体:



接着生成Student对象,然后再拿对象的属性,通常的做法如下:



当然这不是我们想要去做的,而是想通过Supplire函数式接口来生成Student对象并去拿属性,具体怎么做呢?



当然上面的代码还可以更加精简,可以采用构造方法引用【关于方法引用这个到时会仔细学习的,先有个印象既可】来修改:



那为啥"Student::new"就能返回Supplier的实例呢?因为Student的构造方法是不接收参数但是返回Student对象,这不就正好符合Supplier的约定么?下面看一个细节:



上面的效果要归功于IDE的智能,在点击new时自动就跳到了Student的定义,而点"::"时跳到了Supplier的定义。也进一步说明这个方法引用方式可以生成Supplier接口的实例,目前Student类中只有一个默认的构造方法,那如果再加一个非默认的构造方法会有什么情况发生呢?



发现咱们的程序依然可以正常运行,这还得归功于编译器的智能,怎么个智能法呢?





所以就会到Student类中找一个不带参数的但是能返回Student的构造方法,发现不就是默认的构造方法么,如果咱们将默认构造方法注释掉,看有啥反应:



立马就报错了,说明确实如咱们所分析的那样。

当学习到这,基本上就已经将Java8所涉及的重要的函数式接口就已经学习得差不多了,通过合理的搭配这些不同的函数式接口可以帮助我们完成现实中的很多很多的事情。

[b]BinaryOperator接口:[/b]

在函数式接口的学习暂且告一段落之前,最后再来学一个新的函数式接口扩展一下,其实也不是完全的新函数,而是继承咱们之前学习的BiFunction来实现的一个特例,下面看下javadoc对它的描述:



从这句话的描述其实就能感知到:对于BinaryOperator是接受两个参数,而这两个参数的类型是一样的,其返回结果也是跟参数是相同的类型。





但是在BinaryOperator这个接口中貌似也木有找到这个方法呀:



很显然这个方法是从BiFunction继承过来滴,另外再看一下它的泛型声明:





那这个接口存在有啥价值么?还记得之前用BiFunction对两个整数进行了四则运算如下:



但是~~有木有发现两整数四则运算之后的结果是不是也是整数类型,那不正符合BinaryOperator函数式接口的特性么,有了它可以让代码编写更加简洁,下面具体看一下:



比较容易理解,对于这个接口它还有两个静态的方法,下面也来看一下:



看下它的具体实现:



等于是生成一个返回两个数中较少的一个函数式接口,有了它之后再去应用到两数上,并且咱们指定一个比较器之后就可以按咱们自己的规则来返回两数中较小的那个数字啦,下面看下如何来应用它,这里以从两个字串中找出最小的为例:



接下来调用一下:





那接下来更改一下比较规则:字符串首字母的ASCII排前面的则为较小的,如“h”在ASCII表中是排在"w"之前的,所以应该返回"hello123"啦,如下:



对于它的另一个静态方法maxBy就完全不用读就能懂啦,如下:



下面直接应用将其改为maxBy,可想而知其返回就刚好相反啦:



[b]函数式接口总结:[/b]

至此,Java8函数式接口的学习就告一段落了,其函数式接口传递的是行为这个一定得要好好体会,对于Java8中的函数式接口全部位于java.util.function这个包中:



展开包看一下所有的函数式接口:

BiConsumer
BiFunction
BinaryOperator
BiPredicate
BooleanSupplier
Consumer
DoubleBinaryOperator
DoubleConsumer
DoubleFunction
DoublePredicate
DoubleSupplier
DoubleToIntFunction
DoubleToLongFunction
DoubleUnaryOperator
Function
IntBinaryOperator
IntConsumer
IntFunction
IntPredicate
IntSupplier
IntToDoubleFunction
IntToLongFunction
IntUnaryOperator
LongBinaryOperator
LongConsumer
LongFunction
LongPredicate
LongSupplier
LongToDoubleFunction
LongToIntFunction
LongUnaryOperator
ObjDoubleConsumer
ObjIntConsumer
ObjLongConsumer
Predicate
Supplier
ToDoubleBiFunction
ToDoubleFunction
ToIntBiFunction
ToIntFunction
ToLongBiFunction
ToLongFunction
UnaryOperator


其中标红的为咱们已经学习过的,那还有这么多木有学习呀,那怎么办~其实咱们学的是非常之核心的函数式接口,其它木有学习到的函数式接口都是可以触类旁通的,不信下面举几个未学习过的,一看就懂:

Consumer咱们已经学习过了,但是BiConsumer木有学习,但是没关系,可以从Consumer的用法推导出BiConSumer,先回忆下Comsumer:



根据Function跟BiFunction的规则,那BiConsumer很显然就是有两个输入参数无返回值嘛,如下:



它的使用还用学么,依葫芦画瓢~

同样的我们上次刚学习了Predicate,回忆下:



那BiPredicate呢?还需要动脑去学习它的使用方法么?

下面再看:



这么多,其实也就是换了个数据类型而已,拿其中的一个举例:



其它的类型就以此类推,基本上是看一眼就能知道怎么使用,再往下看看:



也拿其中的一个举例:



所以说只学扎实了几个重要的函数式接口就能将所有Java8的函数式接口都学通,当然之后还会大量的对函数式接口进行使用,在未来学习Stream的时候其实就是对Lambda表达式的一个彻底的使用,函数式接口的学习就先到此,下次继续深入Java8其它的一些东东~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: