Java 8 之lambda表达式语法
1. 简介
lambda表达式可以这样定义(不精确,自己的理解):一段带有输入参数的可执行语句块。
//这里省略list的构造
List<String> names = ...;
Collections.sort(names, (o1, o2) -> o1.compareTo(o2));
//这里省略list的构造
List<String> names = ...;
Collections.sort(names, new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return o1.compareTo(o2);}
});
上面两段代码分别是:使用lambda表达式来排序和使用匿名内部类来排序。这个例子可以很明显的看出lambda表达式简化代码的效果。接下来展示lambda表达式和其好基友Stream的配合。
List<String> names = new ArrayList<>();
names.add("TaoBao");
names.add("ZhiFuBao");
List<String> lowercaseNames = names.stream().map((String name) -> {return name.toLowerCase();}).collect(Collectors.toList());
2.Lambda语法详解
我们在此抽象一下lambda表达式的一般语法:
(Type1 param1, Type2 param2, ..., TypeN paramN) -> {
statment1;
statment2;
//.............
return statmentM;
}
从lambda表达式的一般语法可以看出来,还是挺符合上面给出的非精确版本的定义–“一段带有输入参数的可执行语句块”。
下面陆续介绍一下lambda表达式的各种简化版:
2.1 参数类型省略–绝大多数情况,
编译器都可以从上下文环境中推断出lambda表达式的参数类型。这样lambda表达式就变成了:
(param1,param2, ..., paramN) -> {
statment1;
statment2;
//.............
return statmentM;
}
所以我们最开始的例子就变成了(省略了List的创建):
List<String> lowercaseNames = names.stream().map((name) -> {return name.toLowerCase();}).collect(Collectors.toList());
2.2 当lambda表达式的参数个数只有一个,可以省略小括号。lambda表达式简写为:
param1 -> {
statment1;
statment2;
//.............
return statmentM;
}
所以最开始的例子再次简化为:
List<String> lowercaseNames = names.stream().map(name -> {return name.toLowerCase();}).collect(Collectors.toList());
2.3 当lambda表达式只包含一条语句时,
可以省略大括号、return和语句结尾的分号。lambda表达式简化为:
param1 -> statment
所以最开始的例子再次简化为:
List<String> lowercaseNames = names.stream().map(name -> name.toLowerCase()).collect(Collectors.toList());
1.4 使用Method Reference(具体语法后面介绍)
List<String> lowercaseNames = names.stream().map(String::toLowerCase).collect(Collectors.toList());
3. Lambda表达式眼中的外部世界
我们可以这样想:lambda表达式其实是快速创建SAM接口的语法糖,原先的SAM接口都可以访问接口外部变量,lambda表达式肯定也是可以。
String[] array = {"a", "b", "c"};
for(Integer i : Lists.newArrayList(1,2,3)){Stream.of(array).map(item -> Strings.padEnd(item, i, '@')).forEach(System.out::println);
}
上面的这个例子中,map中的lambda表达式访问外部变量Integer i。并且可以访问外部变量是lambda表达式的一个重要特性,这样我们可以看出来lambda表达式的三个重要组成部分:
输入参数
可执行语句
存放外部变量的空间
不过lambda表达式访问外部变量有一个非常重要的限制:变量不可变(只是引用不可变,而不是真正的不可变)。
String[] array = {"a", "b", "c"};
for(int i = 1; i<4; i++){Stream.of(array).map(item -> Strings.padEnd(item, i, '@')).forEach(System.out::println);
}
上面的代码,会报编译错误。因为变量i被lambda表达式引用,所以编译器会隐式的把其当成final来处理(ps:大家可以想象问什么上一个例子不报错,而这个报错。)细心的读者肯定会发现不对啊,以前java的匿名内部类在访问外部变量的时候,外部变量必须用final修饰。Bingo,在java8对这个限制做了优化,可以不用显示使用final修饰,但是编译器隐式当成final来处理。
lambda眼中的this
在lambda中,this不是指向lambda表达式产生的那个SAM对象,而是声明它的外部对象。
4.方法引用(Method reference)和构造器引用(construct reference)
方法引用可以在某些条件成立的情况下,更加简化lambda表达式的声明。方法引用语法格式有以下三种:
objectName::instanceMethod
ClassName::staticMethod
ClassName::instanceMethod
前两种方式类似,等同于把lambda表达式的参数直接当成instanceMethod|staticMethod的参数来调用。比如System.out::println等同于x->System.out.println(x);Math::max等同于(x, y)->Math.max(x,y)。
最后一种方式,等同于把lambda表达式的第一个参数当成instanceMethod的目标对象,其他剩余参数当成该方法的参数。比如String::toLowerCase等同于x->x.toLowerCase()。
构造器引用
构造器引用语法如下:ClassName::new,把lambda表达式的参数当成ClassName构造器的参数 。例如BigDecimal::new等同于x->new BigDecimal(x)。
参考:http://ifeve.com/lambda/
转载于:https://www.cnblogs.com/john8169/p/9780584.html
Java 8 之lambda表达式语法相关推荐
- lambda表达式语法_使用类似Lambda的语法作为Java中的表达式进行切换
lambda表达式语法 从Java 14开始, switch表达式具有其他Lambda式 ( case ... -> labels )语法,它不仅可以用作语句,还可以用作计算为单个值的表达式. ...
- java saf_Java 8 Lambda表达式探险
为什么? 我们为什么需要Lambda表达式 主要有三个原因: > 更加紧凑的代码 比如Java中现有的匿名内部类以及监听器(listeners)和事件处理器(handlers)都显得很冗长 &g ...
- java8 lambda python_【学习笔记】java8 Lambda表达式语法及应用
本文是慕课网大牧莫邪老师的视频教程一课掌握Lambda表达式语法及应用的学习笔记.如果觉得内容对你有用,可以购买老师的课程支持一下,课程价格1元,十分良心了. 1. 课程介绍 2. 为什么引入Lamb ...
- java junit 异常_JUnit:使用Java 8和Lambda表达式测试异常
java junit 异常 在JUnit中,有许多方法可以在测试代码中测试异常,包括try-catch idiom JUnit @Rule和catch-exception库. 从Java 8开始,我们 ...
- JUnit:使用Java 8和Lambda表达式测试异常
在JUnit中,有许多方法可以在测试代码中测试异常,包括try-catch idiom JUnit @Rule和catch-exception库. 从Java 8开始,我们还有另一种处理异常的方法:使 ...
- Java 8:Lambda表达式与自动关闭
如果您通过Neo4j的Java API和Java 6使用了Neo4j的早期版本,则可能具有与以下类似的代码,以确保在事务中进行写操作: public class StylesOfTx {public ...
- java基础之lambda表达式
java基础之lambda表达式 1 什么是lambda表达式 lambda表达式是一个匿名函数,允许将一个函数作为另外一个函数的参数,将函数作为参数传递(可理解为一段传递的代码). 2 为什么要用l ...
- java中的lambda表达式学习
Lambda表达式是给函数式接口(SAM接口)的变量或形参赋值的表达式. Lambda表达式替代了原来使用匿名内部类的对象给函数式接口(SAM接口)的变量或形参赋值的形式. java提供了大量的函数式 ...
- 如何开始使用Java中的Lambda表达式
by Luis Santiago 路易斯·圣地亚哥(Luis Santiago) 如何开始使用Java中的Lambda表达式 (How to start working with Lambda Exp ...
最新文章
- tortoisegit 常见错误disconnected no supported authentication methods available(server sent: publickey)
- SDUT 3258 Square Number 简单数学
- 数学建模 匈牙利算法求解整数规划基本原理与编程实现
- harmonyos公测招募,nova为主 HarmonyOS 2.0开发者Beta公测再招募
- 深入浅出PE文件格式---自己动手打造PE Show
- html5 canvas画布上合成
- mac osx 下的 mysql_Mac OSX下的MySQL数据库升级
- css基础知识汇总5
- qt 增加的翻译没有作用上_Qt翻译文件使用方法
- ENVI实现最小距离法、最大似然法、支持向量机遥感图像监督分类与分类后处理操作
- android 跑马灯带图片,Android自定义跑马灯效果(适合任意布局)
- jmp指令流程图怎么写_NS流程图是什么?规范实用的流程图工具
- 102 613 SWP协议学习笔记--数据链路层
- 我是一名资深程序员,而今天我又多了一个创业者的身份(2)
- Acrel-2000Z变电站综合自动化系统
- 在观察研究中减少数据偏倚:倾向评分(一)
- 动物识别Python
- Android中播放本地SD卡中歌曲需要的添加的权限
- 在linux系统上查看本机ip地址
- PHP实现图片上传功能
热门文章
- keystone 手动建立租户,用户,角色,服务,端口
- 十年编程经验凝结 与新人们分享
- VFP中轻松绑定 Windows 事件
- java write 去bom_Java处理UTF-8带BOM的文本的读写
- 用python写三角形_python写个三角形的问题
- 试分别简述udp和tcp的特点_技术帖:污水处理中曝气设备的分类及特点小结
- php 模板继承原理,模板继承体会
- Vue组件化之VueComponent介绍
- mysql 5.7 单节点多实例_mysql5.7 多实例(第二篇)从节点数据异常
- RocketMQ(三)—— 集群模式的说明