java8学习之深入函数式接口与方法引用
函数式接口:
函数式接口【FunctionalInterface】是整个Lambda表达式的一个根源,换句话来说java8中的Lambda表达式要想彻底掌握,前提是要彻底理解好函数式接口,所以这次继续对函数式接口进行巩固。
先回顾一下上一次通过读FunctionalInterface这个注解的javadoc之后的三点总结【参考:http://www.cnblogs.com/webor2006/p/8111585.html】:

关于FunctionalInterface的doc上有一个细节还需要注意,在上次中也已经提到过,这里再拧出来看一下:


那换成代码如何来理解上面这段话呢?新建一个接口,里面声明一个方法,当然它是抽象的【抽象的概念是只有声明木有具体实现的】:

那这个是不是FuncationalInterface呢?加上注解就可以论证了:

那如果再增加一个抽象方法:

看下报错提示:

那如果此时将这个新加的方法名称换一个是Object类中的呢?

那为什么呢?原因就如javadoc上面的这点所描述:toString()是一个抽象方法,但是Object中也有此方法,细心的可以发现其实开发工具比较智能的在该方法的左侧已经显示出来一个箭头,点击则可以查看它父类的方法:

那点开看一下呗:

很显然该方法是复写的Object类的中方法,所以java编译器不认为该方法是一个抽象方法,所以当然整个接口还是满足只有一个抽象方法的条件,当然认为此时的接口还是一个函数式接口啦。这是表现上的理论,那为啥要有这样的一个规定呢?其实也比较好理解:如果一个类实现该接口,那很明显该类一定有这两个方法的实现,然而java.lang.Object是所有类的父类,也就是说明具体类都会直接或间接的继承Object类中的方法,而toString()并非是子类特有的方法,所以说如果一个方法中声明的刚好是Object类中的方法,那它不算抽象方法。
接下来继续用代码来进行延深:

由于MyInterface是函数式接口,所以可以改用Lambda表达式,如下:

其实上面标红的Lamdba表达式的写法就是MyInterface的匿名实现类,所以程序可以这样写:

那咱们可以打印一下这个类和它父类名字,如下:

那这个myInterface类的具体实现的接口是哪些呢?接着可以打印一下:

那这接口是谁呢?继续打印:

通过上面的例子对于函数式接口应该有一个比较好的认识了,所以对于它的探讨先暂时到这,接下来对于之前的例子进行一个进一步的探讨,回顾下当时的代码:

通过三种方式来对一个集合进行遍历,这里将重点观注在最后一种用函数式接口的方式,那这个forEach方法是来自于List类中么?点击查看下源码:

来自于Iterable接口当中,可以看到该方法是从Java1.8才开始引入的,但是Iterable是从1.5就开始引入的:

而我们知道List最终是实现了Iterable这个接口,所以当然也就继承有forEach这个方法啦,这就解释了为啥可以通过List去直接调用forEach来达到遍历的目的。
这里需要注意一下细节,这个forEach方法的具体实现实际上就是写在Iterable接口当中的,但是在接口的声明前面有个default关键字,这个也在之前说了,在Java8以后在接口中可以有具体实现了,但凡在接口中有具体实现方法,前面必须加default的关键字,这称之为默认方法(Default Method),而对于实现这个接口的类也自然而然继承有这个默认方法了,有点像抽象类的概念:类中既可有抽象方法,也可以有具体方法,而继承类也会继承抽象类的具体方法。
接着来查看一下forEach javadoc的注释:




接下来再来看一下这个指定的动作Consumer,从字面意思来理解当然就是消费者的意思啦,点击看一下它的源码:

读一下接口的doc:




再回到咱们的程序来说,很显然可以换成Lambda表达式来改造,所有函数式接口都可以采用Lambda表达式来编写,如下:

下面再对Lambda表达式进行一个总结。
Lambda表达式作用:
- Lambda表达式为Java添加了缺失的函数式编程特性,使得我们能将函数当做一等公民对待。
因为Java在以前方法永远都是依附于类而存在的,不可以独立存在的, 现在我们可以将方法当作参数进行传递了, 所以函数在Java8里面就成了一等公民。 - 在将函数作为一等公民的语言中,Lambda表达式的类型是函数,但在Java中,Lambda表达式是对象,他们必须依咐于一类特别的对象类型---函数式接口(Functional Interface)
标红的说Lambda表达式是对象,为什么呢?
迭代方式:
外部迭代:
什么是外部迭代呢?看程序:

下面用图来更形象的理解:

然后一个个元素进行迭代,最后指向一个空的元素既迭代完成了,如下:

内部迭代:
何为内部迭代,直接看代码:

之所以叫内部迭代,相对于外部迭代,当然是没有了外部迭代的迭代器啦,不借助于外部力量既完成元素的迭代。
方法引用:
对于上面元素迭待的方式已经改用Lambda表达式去写,代码已经很精简了,但是!!还可以更加精简,如下:

对于上面这种写法就叫做方法引用(method references),而这个forEach方法参数是函数式接口的实例,那意思是这个方法引用能创建函数式接口的实例?是的,在查看函数式注解的javadoc上就已经清楚的说明了,这里再来回顾一下:

这里看一个IDE比较智能的地方,就是在方法引用语句中的"::"处点击ctrl键之后会看到:

自动就跳到了Consumer这个函数式接口了,说明编译器识别到了这种定法就是对Consumer接口的实现,关于方法引用在之后还会仔细学习,这里有个感性的认识就行。
java8学习之深入函数式接口与方法引用的更多相关文章
- Java8 Lambda表达式、函数式接口和方法引用
目录 Java8 Lambda表达式和函数式接口 Lambda表达式 Lambda的使用 函数式接口FunctionalInterface Java内置四大核心函数式接口 方法引用 构造器引用 Jav ...
- 009-jdk1.8版本新特性一-展方法,Lambda表达式,函数式接口、方法引用构造引用
一.JDK1.8 名称:Spider(蜘蛛) 发布日期:2014-03-18 新特性: 1.1.扩展方法[接口的默认方法] Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 defaul ...
- java8学习之BiFunction函数式接口实例演示&Predicate函数式接口详解
BiFunction函数式接口: 在上次中已经对BiFunction接口进行了初步的认识,这里对它进一步学习,这里打算新建一个Person实体,然后新建若干个Person的实例存放在集合中,最后再根据 ...
- JDK1.8新特性(一) ----Lambda表达式、Stream API、函数式接口、方法引用
jdk1.8新特性知识点: Lambda表达式 Stream API 函数式接口 方法引用和构造器调用 接口中的默认方法和静态方法 新时间日期API default Lambda表达式 L ...
- 乐字节-Java8新特性之函数式接口
上一篇小乐带大家学过 Java8新特性-Lambda表达式,那什么时候可以使用Lambda?通常Lambda表达式是用在函数式接口上使用的.从Java8开始引入了函数式接口,其说明比较简单:函数式接口 ...
- Java8新特性之函数式接口
<Java 8 实战>学习笔记系列 定义 函数式接口只定义一个抽象方法,可以有多个默认方法 函数式接口的接口名上,会被@FunctionalInterface标注 作用 函数式接口的方法可 ...
- Lambda学习总结(一)--函数式接口
Lambda 表达式是 JDK 1.8 里面的一个重要更新,这意味着 Java 也开始承认了函数式编程,并且尝试引入其中,我们今天就来了解下它的使用. 一.函数式接口 1.1 概念 函数式接口在 Ja ...
- Java8一Lambda与函数式接口
关于Lambda表示在工作学习中会经常用到,但并没有全面的去了解.在这里做一个较为详细的记录供以后学习查阅.主要参考Java 8 Lambda 表达式 引言 Java8之前,我们在使用Runnale创 ...
- Java8内置的函数式接口
JDK 1.8 API 包含了很多内置的函数式接口.其中就包括我们在老版本中经常见到的 Comparator 和 Runnable,Java 8 为他们都添加了 @FunctionalInterfac ...
随机推荐
- python3 速查参考- python基础 6 -> 函数编程之参数、变量、作用域、递归、匿名函数 lambda
函数基础 1. 速查笔记 #-- 函数相关的语句和表达式 myfunc('spam') # 函数调用 def myfunc(): # 函数定义 return None # 函数返回值 global a ...
- android#boardcast#广播实现强制下线功能
参考自<第一行代码>——郭霖 强制下线功能需要先关闭掉所有的活动(Activity),然后回到登录界面.先创建一个ActivityCollector类用于管理所有的活动,代码如下所示: p ...
- 【HTML】常用的标签学习(2)
现在的使用的html语言都是h5,但是h5也是从h4继承发展来的,所以h4的标签我们也要学习,然后加上h5新增的标签,那么html这门语言才算学习完毕.上次学习了h4的一些常用标签,今天学习h4剩下的 ...
- php screw加密与破解
一.破解工具之php-screw-brute 1.项目地址 https://github.com/securifybv/php-screw-brute 2.项目介绍 此脚本可以恢复/爆破php scr ...
- Linux下ping: unknown host www.baidu.com的解决办法
如果ping域名的时候出现ping:unknown host xxx.xxx 但是ping IP地址的时候可以通的话 可知是dns服务器没有配置好, 查看一下配置文件/etc/resolv.conf ...
- [Nowcoder212D]禁书目录_概率期望
禁书目录 题目大意:清教需要定期给Index清除记忆,在此之前需要把当中的十万三千本禁书取出来......不幸的是,禁书一旦离开了Index就非常脆弱,具体来说,每一本禁书都有一个魔力值 ai ,其记 ...
- Postfix to Prefix Conversion & Prefix to Postfix Conversion
Postfix to Prefix Conversion Postfix: An expression is called the postfix expression if the operator ...
- [转帖]yum与apt-get的区别以及两者更新源(阿里/网易【163】)
yum与apt-get的区别以及两者更新源(阿里/网易[163]) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/one_super_dreamer ...
- (4.35)sql server清理过期文件【转】
在SQL Server中, 一般是用维护计划实现删除过期文件.不过直接用脚本也是可以的,而且更灵活. 下面介绍三种方法, 新建一个作业, 在作业的步骤里加上相关的脚本就可以了. --1. xp_del ...
- windows下将多个文件合并成一个文件,将ts文件变成MP3格式
①:先把全部的ts文件下载下来放到指定文件夹,这里我是放在桌面的ls里 ②:从cmd进去找到桌面的路径,也可以像我这样直接在桌面的路径上敲cmd进入: ③:直接合并使用命令“copy /b ls\*. ...