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表达式语法相关推荐

  1. lambda表达式语法_使用类似Lambda的语法作为Java中的表达式进行切换

    lambda表达式语法 从Java 14开始, switch表达式具有其他Lambda式 ( case ... -> labels )语法,它不仅可以用作语句,还可以用作计算为单个值的表达式. ...

  2. java saf_Java 8 Lambda表达式探险

    为什么? 我们为什么需要Lambda表达式 主要有三个原因: > 更加紧凑的代码 比如Java中现有的匿名内部类以及监听器(listeners)和事件处理器(handlers)都显得很冗长 &g ...

  3. java8 lambda python_【学习笔记】java8 Lambda表达式语法及应用

    本文是慕课网大牧莫邪老师的视频教程一课掌握Lambda表达式语法及应用的学习笔记.如果觉得内容对你有用,可以购买老师的课程支持一下,课程价格1元,十分良心了. 1. 课程介绍 2. 为什么引入Lamb ...

  4. java junit 异常_JUnit:使用Java 8和Lambda表达式测试异常

    java junit 异常 在JUnit中,有许多方法可以在测试代码中测试异常,包括try-catch idiom JUnit @Rule和catch-exception库. 从Java 8开始,我们 ...

  5. JUnit:使用Java 8和Lambda表达式测试异常

    在JUnit中,有许多方法可以在测试代码中测试异常,包括try-catch idiom JUnit @Rule和catch-exception库. 从Java 8开始,我们还有另一种处理异常的方法:使 ...

  6. Java 8:Lambda表达式与自动关闭

    如果您通过Neo4j的Java API和Java 6使用了Neo4j的早期版本,则可能具有与以下类似的代码,以确保在事务中进行写操作: public class StylesOfTx {public ...

  7. java基础之lambda表达式

    java基础之lambda表达式 1 什么是lambda表达式 lambda表达式是一个匿名函数,允许将一个函数作为另外一个函数的参数,将函数作为参数传递(可理解为一段传递的代码). 2 为什么要用l ...

  8. java中的lambda表达式学习

    Lambda表达式是给函数式接口(SAM接口)的变量或形参赋值的表达式. Lambda表达式替代了原来使用匿名内部类的对象给函数式接口(SAM接口)的变量或形参赋值的形式. java提供了大量的函数式 ...

  9. 如何开始使用Java中的Lambda表达式

    by Luis Santiago 路易斯·圣地亚哥(Luis Santiago) 如何开始使用Java中的Lambda表达式 (How to start working with Lambda Exp ...

最新文章

  1. tortoisegit 常见错误disconnected no supported authentication methods available(server sent: publickey)
  2. SDUT 3258 Square Number 简单数学
  3. 数学建模 匈牙利算法求解整数规划基本原理与编程实现
  4. harmonyos公测招募,nova为主 HarmonyOS 2.0开发者Beta公测再招募
  5. 深入浅出PE文件格式---自己动手打造PE Show
  6. html5 canvas画布上合成
  7. mac osx 下的 mysql_Mac OSX下的MySQL数据库升级
  8. css基础知识汇总5
  9. qt 增加的翻译没有作用上_Qt翻译文件使用方法
  10. ENVI实现最小距离法、最大似然法、支持向量机遥感图像监督分类与分类后处理操作
  11. android 跑马灯带图片,Android自定义跑马灯效果(适合任意布局)
  12. jmp指令流程图怎么写_NS流程图是什么?规范实用的流程图工具
  13. 102 613 SWP协议学习笔记--数据链路层
  14. 我是一名资深程序员,而今天我又多了一个创业者的身份(2)
  15. Acrel-2000Z变电站综合自动化系统
  16. 在观察研究中减少数据偏倚:倾向评分(一)
  17. 动物识别Python
  18. Android中播放本地SD卡中歌曲需要的添加的权限
  19. 在linux系统上查看本机ip地址
  20. PHP实现图片上传功能

热门文章

  1. keystone 手动建立租户,用户,角色,服务,端口
  2. 十年编程经验凝结 与新人们分享
  3. VFP中轻松绑定 Windows 事件
  4. java write 去bom_Java处理UTF-8带BOM的文本的读写
  5. 用python写三角形_python写个三角形的问题
  6. 试分别简述udp和tcp的特点_技术帖:污水处理中曝气设备的分类及特点小结
  7. php 模板继承原理,模板继承体会
  8. Vue组件化之VueComponent介绍
  9. mysql 5.7 单节点多实例_mysql5.7 多实例(第二篇)从节点数据异常
  10. RocketMQ(三)—— 集群模式的说明