java8学习之Supplier与函数式接口总结
Supplier接口:
继续学习一个新的函数式接口--Supplier,它的中文意思为供应商、提供者,下面看一下它的javadoc:
而具体的方法也是相当的简单,就是不接受任何参数,返回一个结果:
对它有了大概的了解之后,下面用代码来使用一下它:
貌似这函数的使用相当简单呀,但是简单并非是它的用处少,那它到底可以应用在现实中的什么场合之下呢?工厂就是其一,因为工厂有时里面是不接收参数的,直接从工厂里面返回一个结果,当然如果工厂里面要接收参数且返回结果那Function函数式接口就可以派上用场了,下面还是看一下这种Supplier的场景:
首先定义一个实体:
接着生成Student对象,然后再拿对象的属性,通常的做法如下:
当然这不是我们想要去做的,而是想通过Supplire函数式接口来生成Student对象并去拿属性,具体怎么做呢?
当然上面的代码还可以更加精简,可以采用构造方法引用【关于方法引用这个到时会仔细学习的,先有个印象既可】来修改:
那为啥"Student::new"就能返回Supplier的实例呢?因为Student的构造方法是不接收参数但是返回Student对象,这不就正好符合Supplier的约定么?下面看一个细节:
上面的效果要归功于IDE的智能,在点击new时自动就跳到了Student的定义,而点"::"时跳到了Supplier的定义。也进一步说明这个方法引用方式可以生成Supplier接口的实例,目前Student类中只有一个默认的构造方法,那如果再加一个非默认的构造方法会有什么情况发生呢?
发现咱们的程序依然可以正常运行,这还得归功于编译器的智能,怎么个智能法呢?
所以就会到Student类中找一个不带参数的但是能返回Student的构造方法,发现不就是默认的构造方法么,如果咱们将默认构造方法注释掉,看有啥反应:
立马就报错了,说明确实如咱们所分析的那样。
当学习到这,基本上就已经将Java8所涉及的重要的函数式接口就已经学习得差不多了,通过合理的搭配这些不同的函数式接口可以帮助我们完成现实中的很多很多的事情。
BinaryOperator接口:
在函数式接口的学习暂且告一段落之前,最后再来学一个新的函数式接口扩展一下,其实也不是完全的新函数,而是继承咱们之前学习的BiFunction来实现的一个特例,下面看下javadoc对它的描述:
从这句话的描述其实就能感知到:对于BinaryOperator是接受两个参数,而这两个参数的类型是一样的,其返回结果也是跟参数是相同的类型。
但是在BinaryOperator这个接口中貌似也木有找到这个方法呀:
很显然这个方法是从BiFunction继承过来滴,另外再看一下它的泛型声明:
那这个接口存在有啥价值么?还记得之前用BiFunction对两个整数进行了四则运算如下:
但是~~有木有发现两整数四则运算之后的结果是不是也是整数类型,那不正符合BinaryOperator函数式接口的特性么,有了它可以让代码编写更加简洁,下面具体看一下:
比较容易理解,对于这个接口它还有两个静态的方法,下面也来看一下:
看下它的具体实现:
等于是生成一个返回两个数中较少的一个函数式接口,有了它之后再去应用到两数上,并且咱们指定一个比较器之后就可以按咱们自己的规则来返回两数中较小的那个数字啦,下面看下如何来应用它,这里以从两个字串中找出最小的为例:
接下来调用一下:
那接下来更改一下比较规则:字符串首字母的ASCII排前面的则为较小的,如“h”在ASCII表中是排在"w"之前的,所以应该返回"hello123"啦,如下:
对于它的另一个静态方法maxBy就完全不用读就能懂啦,如下:
下面直接应用将其改为maxBy,可想而知其返回就刚好相反啦:
函数式接口总结:
至此,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其它的一些东东~
java8学习之Supplier与函数式接口总结的更多相关文章
- Java8常用的内置函数式接口(一)Predicate、Consumer、Supplier、Function
Java8常用的内置函数式接口(一) 简介 JDK 1.8 API中包含了很多内置的函数式接口.有些是在以前版本的Java中大家耳熟能详的,例如Comparator接口,或者Runnable接口.对这 ...
- java8的4大核心函数式接口
//java8的4大核心函数式接口//1.Consumer<T>:消费性接口//需求:public void happy(double money, Consumer<Double& ...
- 乐字节-Java8核心特性实战之函数式接口
什么时候可以使用Lambda?通常Lambda表达式是用在函数式接口上使用的.从Java8开始引入了函数式接口,其说明比较简单:函数式接口(Functional Interface)就是一个有且仅有一 ...
- java8中规范的四大函数式接口
java8中规范的四大函数式接口: 1.Consumer<T> :消费型接口 void accept(T t); 2.Supplier<T> :供给型接口 ...
- Java8新特性探索之函数式接口
一.为什么引入函数式接口 作为Java函数式编程爱好者,我们都知道方法引用和 Lambda 表达式都必须被赋值,同时赋值需要类型信息才能使编译器保证类型的正确性. 我们先看一个Lambda代码示例: ...
- Java8学习笔记(四)--接口增强
增强点 静态方法 public interface InterfacePlus { void run(); static Date createDate(){ return new Date(); } ...
- java8新特性 - 什么是函数式接口 @FunctionalInterface?
什么是函数式接口 @FunctionalInterface 源码定义 /** * An informative annotation type used to indicate that an int ...
- java8 函数式接口——Function/Predict/Supplier/Consumer
Function 我们知道Java8的最大特性就是函数式接口.所有标注了@FunctionalInterface注解的接口都是函数式接口,具体来说,所有标注了该注解的接口都将能用在lambda表达式上 ...
- java8新特性——四大内置核心函数式接口
在前面几篇简单介绍了一些Lambda表达式得好处与语法,我们知道使用Lambda表达式是需要使用函数式接口得,那么,岂不是在我们开发过程中需要定义许多函数式接口,其实不然,java8其实已经为我们定义 ...
随机推荐
- Django-DRF(1)
一. WEB应用模式 在开发Web应用中,有两种应用模式: 1. 前后端不分离 2. 前后端分离 二. API接口 为了在团队内部形成共识.防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的 ...
- speedtest-cli 命令
speedtest-cli是一个使用python编写的命令行脚本,通过调用speedtest.net测试上下行的接口来完成速度测试,项目地址:https://github.com/sivel/spee ...
- Design Phone Directory
Design a Phone Directory which supports the following operations: get: Provide a number which is not ...
- 【转帖】docker-get拉取镜像
docker-get拉取镜像 题目很诱人 找时间测试一下 是否可以翻越长城下载镜像. https://www.cnblogs.com/fuyuteng/p/10904495.html docker-g ...
- Linux(CentOS)下安装NVIDIA GPU驱动
GCC 官网:http://gcc.gnu.org 1)检查 NVIDIA驱动需要GCC等C/C++开发环境,首先检测GCC是否已经安装 gcc –v# 如果系统显示没有找到GCC指令,或没有显示GC ...
- mysql之存储过程基础
存储过程 procedure 可以理解为一个处理增删改,没有返回值得函数 创建存储过程的基本语法 create procedure 过程名 ([参数列表]) begin --过程体 end 存储过程主 ...
- MYSQL---触发器简单了解
触发器 trigger 1.触发器是指事先为某张表绑定一段代码,当表中某些内容发生改变(增insert.删delete.改update)时,系统自动触发绑定的那段代码并执行.比如 一旦订单表里插入新订 ...
- springboot打包的jar项目,不需要安装jdk环境启动
因为服务器上是JDK7,而springboot至少用JDK8才行,但是又因为是很老的项目,不是很清楚能不能换JDK8,有风险,因此选择以前项目用JDK7,而新的springboot用JDK8.步骤一: ...
- Gluster的搭建和使用
Gluster的搭建和使用 序言 我们为什么要去使用分布式存储,在一家大型公司或者大规模的集群中,大家可能会经常遇到一个问题,我的数据怎么存放,放在那,数据空间不够了怎么办,这些问题经常困扰着我们. ...
- TreeSet——实现Comparable接口并重写CompareTo()方法
TreeSet是以自然顺序存的数据,例如 Set<Student> students=new TreeSet(); students.add(new Student("111&q ...