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 ...
最新文章
- 报名 | 第三期医工结合系列研讨会:科研领域的知识产权保护
- 计算机视觉与深度学习 | 开源SLAM、视觉里程计综述(SLAM、Visual Odometry)
- VTK:PolyData之IsoLines
- 机器学习算法的基础知识
- Linux基础命令---fold
- 【渝粤教育】电大中专沟通技巧答案作业 题库
- django框架学习文档_Python四大主流网络编程框架,你知道么?
- 德国院士:“工业4.0”概念升级了,包含人工智能和5G
- cstring移除指定字符串_从String中移除空白字符的多种方式!?差别竟然这么大!...
- C# 3.0入门系列(三)
- string获取 倒数 下标_NBA球星福克斯沉迷LOL,排名美服倒数98名!胜率太真实了...
- WinEdt LaTex(三)—— 宏包
- 北风网VIP6级学习视频地址
- c语言tc环境下while多大,求救,wintc环境下,写了程序,调试不出来,先谢谢了...
- 【PR】简单一招教你使用蒙版做文字动画
- ThreadPoolExecutor-线程池的理解
- Pytorch+PyG实现GraphSAGE
- js获取指定日期的前一年(需要判断闰年和平年)
- c#实现简单的手写板功能
- PMO只是PM的工具人?太肤浅了
热门文章
- HTML5第一弹:彩虹爆炸图
- 性能报告——使用AOP与DYNAMICProxy的orm性能测试
- matlab 过度曝光,MATLAB:补偿图像处理中的过度曝光/过饱和度
- 简述台式计算机创建家庭组的步骤,如何创建和设置家庭组
- 雪花怎么画_平安夜怎么过?画个圣诞妆,你是最迷人嘎,你知道吗
- 5-6pooling层
- linux中文件大小设置函数,truncate函数和ftruncate修改文件大小-linux
- java 展现层框架_spring快速入门例子教程:06展现层
- Java 并发编程之 CopyOnWriteArrayList
- 向服务器上传文件的命令,上传文件到远程服务器的命令