<JAVA8新增内容>关于匿名内部集合和lambda表达式
要想说清楚JAVA中的Lambda表达式,必须想讲一下匿名内部类来帮助理解本质。
一.匿名内部类
匿名内部类适合创建那种只需要一次使用的类,例如前面介绍命令模式时所需要的Command对象,匿名内部类的语法有点奇怪,创建匿名内部类时会立即创建一个该类的实例,这个类的定义立即消失,匿名内部类不能重复使用。
语法格式一般如下:
new 实现接口() | 父类构造器 (实参列表){
//匿名内部类的类体部分
}
从上面可以看出,匿名内部类必须继承一个父类,或者实现一个接口,但最多只能继承一个父类,或者实现一个接口。
关于匿名内部类还有如下两条规则:
1.匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象,因此不允许将匿名内部类定义为抽象类。
2.匿名内部类不能定义构造器(Constructor),由于匿名内部类没有类名,所以无法定义构造器,但匿名构造类可以定义初始化块,可以通过实例初始化块来完成构造函数需要完成的部分。
Example 1:
interface MyInter{
public String getName();
}
public class AnonymousTest{
public void test(MyInter i){
System.out.println("The Content of this function is "+i.getName());
}
public static void main(String[] args){
AnonymousTest ta;
ta.test(new MyInter(){
public String getName(){
return "Anonymous Content";
}
});
}
以上的代码等价的实现类对象的代码是:
class AnonymousEqual implements MyInter{
public String getName(){
return "Anonymous Class Content";
}
}
Example 2:
abstract class MyUpperClass{
private String name;
public abstract String getName();
public MyUpperClass(){}
public MyUpperClass(String s){ name=s; }
}////Abstract instead of Interface
public class AnonymousTest{
public void test(MyUpperClass m){
System.out.println("The Content of This Method is "+m.getName());
}
//////////////
public static void main(String[] args){
AnonymousTest at;
at.test(new MyUpperClass("Abstract Class Derived Content"){
public String getName(){
return "AnonymousClass Derived Content";
}
});
}
}
二.Lambda表达式
Lambda表达式是Java8的重要更新,也是一个被广大开发者期待已久的新特性。Lambda表达式支持将代码块作为参数,Lambda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例。
Lambda表达式完全可以用于简化创建匿名内部类对象,因此可将上面中的Example 1中的代码改写成如下的形式。
public class AnonymousTest{
public void test(MyInter i){
System.out.println("The Content of This Method is "+i.getName());
}
//////////////////
public static void main(String []args){
AnonymousTest at;
at.test(()->new String("Lambda Content"));
}
}
从上面的程序之中可以看出,这段代码之中Lambda表达式所实现的test方法和匿名内部类所实现的test方法是完全等价的,只是不再需要一个繁琐的代码块重新声明一个匿名类,不需要重新指出所重写的方法的名字,也不需要给出重写的方法的返回值类型。
从上面的方法之中可以看出,lambda表达式代替匿名内部类的时候,lambda代码块将会实现代替实现抽象类的方法体,lambda表达式的语法主要由三部分构成:
(1)形参列表,如果只有一个参数可以省略括号,当无参数类型时可以使用()或者obj来代替。
(2)箭头(->)
(3)代码块部分,如果代码只有一行则可以省略掉花括号,不然使用花括号将lambda表达式的代码部分标记出来。
Lambda表达式的类型,也被称为“目标类型(target type)”,lambda表达式的目标类型必须是“函数式接口(functional interface)”。函数式接口代表只包含一个抽象方法的接口。函数式接口可以包含多个默认方法,类方法,但只能声明一个抽象方法。如果采用匿名类型内部类来创建函数式接口的实例,则只需要实现一个抽象方法,在这种情况下即可采用lambda表达式来创建对象,该表达式创建出来的对象目标就是这个函数接口。(可以用@FunctionalInterface注解来对函数接口实行限制)
##表达式的目标类型必须是明确的函数式接口
##lambda表达式只能为函数式接口创建对象,lambda表达式只能实现一个方法,因此他它只能为只有一个抽象方法的借口(函数式接口)创建对象。
另外需要注意的一点是: Object不是函数式接口
为了保证lambda表达式的目标类型是一个明确的函数式接口,可以有如下三种常见的方法:
##将lambda表达式赋值给函数式接口类型的变量
##将lambda表达式当作参数传递给需要函数式接口类型的参数的调用方法
##使用函数式接口对lambda表达式进行强制的类型转换
附:
在java.util.function包预定下了大量函数式接口,典型的包含如下4类接口。
***Function:这类接口通常包含一个apply抽象方法,对参数进行处理转换,然后返回一个新的值。
***Consumer:这类接口通常包含一个accept抽象方法,用于对参数进行处理,但是不返回一个新的值。
***Predicate:这类接口通常包含一个test抽象方方法,通过对参数的处理计算,然后返回一个boolean值
***Supplier:这类接口通常包含一个getAs***抽象方法,这种方法无参数,按照某种逻辑运算返回一个数据值。
<JAVA8新增内容>关于匿名内部集合和lambda表达式的更多相关文章
- 闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别
闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别 函数最常见的形式是具名函数(named function): function foo(){ con ...
- <JAVA8新增内容>关于集合的操作(Collection/Iterator/Stream)
因为下文频繁使用lambda表达式,关于Java中的lambda表达式内容请见: http://www.cnblogs.com/guguli/p/4394676.html 一.使用增强的Iterato ...
- 转载 C#匿名函数 委托和Lambda表达式
转载原出处: http://blog.csdn.net/honantic/article/details/46331875 匿名函数 匿名函数(Anonymous Function)是表示“内联”方法 ...
- Java8 新特性----函数式接口,以及和Lambda表达式的关系
这里来讲解一下Java8 新特性中的函数式接口, 以及和Lambda 表达式的关系.看到过很多不少介绍Java8特性的文章,都会介绍到函数式接口和lambda表达式,但是都是分别介绍,没有将两者的关系 ...
- 多播委托和匿名方法再加上Lambda表达式
多播委托就是好几个方法全都委托给一个委托变量 代码: namespace 委托 { class Program { static void math1() { Console.WriteLine(&q ...
- Java8特性详解 lambda表达式 Stream
1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正 ...
- Java8特性详解 lambda表达式 Stream【转】
本文转自http://www.cnblogs.com/aoeiuv/p/5911692.html 1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有 ...
- 【Java学习笔记之三十一】详解Java8 lambda表达式
Java 8 发布日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Java 8之前 ...
- Java8之lambda表达式
一.什么是lambda表达式? Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码 ...
随机推荐
- 【Salvation】——怪物角色动画&主角碰撞死亡动画
写在前面:这个动画功能同样也是使用JavaScript编写脚本,在Unity3D游戏引擎的环境中实现,在怪物的角色动画中,很多与人物相同,这里不再重复. 一.设计敌人 拖一个精英sprite到层次面板 ...
- Java架构师与开发者提高效率的10个工具
Java受到全球百万计开发者的追捧,已经演变为一门出色的编程语言.最终,这门语言随着技术的变化,不断的被改善以迎合变化的市场需求. 无论你是否拥有一家科技公司,软件已经成为几乎每一个企业不可或缺的一部 ...
- "贪心法"
有没有想过 “==” 和“= =” 的区别 , 万一编译器曲解了你的意思,那不是爽歪歪! C语言编译器会把前面的符号当做一个整体,后面的不再. 当我们遇到指针相除时: y=x/*p 编译器会怎样? 和 ...
- 出现“Windows资源管理器已停止工作”错误
出现"Windows资源管理器已停止工作"错误 什么是资源管理器呢,explorer.exe进程的作用就是让我们管理计算机中的资源! 今天开电脑的时候就一直提示windows资源管 ...
- Odoo11 新功能 : 栏位隐藏
Odoo11增加了一个 新的 modifier-. 先上 前端框架代码 invisible / readonly / required 这几个 是经常在用的, column_invis ...
- UNP学习笔记(第十七章 ioctl操作)
ioctl相当于一个杂物箱,它一直作为那些不适合归入其他精细定义类别的特性的系统接口. 本章笔记先放着,到时候有需要再看 ioctl函数 #include <unistd.h> int i ...
- 【Excle数据透视表】如何重命名数据透视表
如下图,是新生成的一个数据透视简表,现在需要将其数据透视表的名称修改为:汇总数据 解决办法 修改后的效果如下:
- vue proxyTable
Vue-cli proxyTable 解决开发环境的跨域问题 字数474 阅读1685 评论1 喜欢3 和后端联调时总是会面对恼人的跨域问题,最近基于Vue开发项目时也遇到了这个问题,两边各自想了一堆 ...
- Maven上传本地jar
1. 将Jar包安装到本地仓库 -- DgroupId和DartifactId构成了该jar包在pom.xml的坐标, 对应依赖的DgroupId和DartifactId -- Dfile表示需 ...
- sphinx PDF 中文
使用reST撰写文档时,需要分多个文档时,就必须使用sphinx了,sphinx说起来很简单的,但是默认是不是支持中文的.幸好我出生的晚,sphinx现在已经支持xelatex了^_^ 安装 除了pa ...