死磕Lambda表达式(三):更简洁的Lambda
我们都是阴沟里的虫子,但总还是得有人仰望星空。——《三体》
在之前的文章中介绍了Lambda表达式的基本语法和正确使用姿势,这次我来介绍一些Lambda更简洁的用法。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
类型推断
编译器可以通过函数式接口推断出Lambda表达式的参数类型,所以在编写Lambda表达式时,可以省略参数类型。比如:
Comparator<Mask> comparator = (Mask o1, Mask o2) -> o1.getBrand().compareTo(o2.getBrand());
就可以简写为:
Comparator<Mask> comparator = (o1, o2) -> o1.getBrand().compareTo(o2.getBrand());
另外,当Lambda表达式只有一个参数的时候,不仅可以省略参数类型,还可以省略到参数名称两边的括号,比如:
Predicate<Mask> predicate = (Mask mask) -> mask.getType() == "N95";
就可以简写为:
Predicate<Mask> predicate = mask -> mask.getType() == "N95";
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
方法引用
什么是方法引用?
方法引用是Java8中引入的新特性,它提供了一种引用方法而不执行方法的方式,可以让我们重复使用现用方法的定义,做为某些Lambda表达式的另一种更简洁的写法。
比如前面的例子:
Comparator<Mask> comparator = (o1, o2) -> o1.getBrand().compareTo(o2.getBrand());
使用方法引用以后,可以简写为:
Comparator<Mask> comparator = Comparator.comparing(Mask::getBrand);
当你需要方法引用时,目标引用放在分隔符::前,方法的名称放在分隔符::后。比如,上面的Mask::getBrand,就是引用了Mask中定义的getBrand方法。方法名称后不需要加括号,因为我们并没有实际调用它。方法引用提高了代码的可读性,也使逻辑更加清晰。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
怎么构建方法引用?
可以构建方法引用的场景的有四种:
1. 静态方法
指向静态方法的引用,语法:类名::静态方法名,类名放在分隔符::前,:静态方法名放在分隔符::后。比如:
(String str) -> Integer.parseInt(str)
使用方法引用以后,可以简写为:
Integer::parseInt
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
2. 内部对象的实例方法
指向Lambda表达式内部对象的实例方法的引用,语法:类名::实例方法名,类名放在分隔符::前,:实例方法名放在分隔符::后。比如:
(Mask mask) -> mask.getBrand()
使用方法引用以后,可以简写为:
Mask::getBrand
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
3. 外部对象的实例方法
指向Lambda表达式外部对象的实例方法的引用,语法:实例名::实例方法名,类名放在分隔符::前,:实例方法名放在分隔符::后。比如:
String type = "N95";
Predicate<String> predicate = (String str) -> type.equals(str);
System.out.println(predicate.test("N95"));
其中,type是一个Lambda表达式外部的局部变量,使用方法引用以后,可以简写为:
String type = "N95";
Predicate<String> predicate = type::equals;
System.out.println(predicate.test("N95"));
如果对于Predicate接口还不熟悉,没关系,以后的文章会介绍到,这里暂且知道它的抽象方法的签名是(T) -> boolean就可以了。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
4. 构造方法
指向构造方法的引用,语法:类名::new,类名放在分隔符::前,new放在分隔符::后。比如:
(String brand, String type) -> new Mask(brand, type)
使用方法引用以后,可以简写为:
Mask::new
小测试
看了这么多,是不是摩拳擦掌准备试一试了?我们就来一个小测试:
(char[] array) -> new String(array)(String str) -> str.length()(String type) -> mask.setType(type),其中的mask是一个Mask对象的局部变量。(String str) -> System.out.println(str)
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
请思考片刻…
.
.
.

.
.
.
宣布答案:
- 因为
(char[] array) -> new String(array)是一个构造方法的Lambda表达式,此种方法引用的语法是:类名::new,所以正确答案是:String::new。 - 因为
(String str) -> str.length()是一个内部对象的实例方法的Lambda表达式,此种方法引用的语法是:类名::实例方法名,所以正确答案是:String::length。 - 因为
(String type) -> mask.setType(type)中的mask是一个Mask对象的局部变量,它是一个包含外部对象的Lambda表达式,此种方法引用的语法是:实例名::实例方法名,所以正确答案是mask::setType。 - 因为
(String str) -> System.out.println(str)是一个静态方法的Lambda表达式,此种方法引用的语法是:类名::静态方法名,所以正确答案是System.out::println。
怎么样?都答对了嘛?
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
《死磕Lambda表达式》系列
- 死磕Lambda表达式(一):初识Lambda
- 死磕Lambda表达式(二):Lambda的使用
- 死磕Lambda表达式(三):更简洁的Lambda
- 死磕Lambda表达式(四):常用的函数式接口
- 死磕Lambda表达式(五):Comparator复合
- 死磕Lambda表达式(六):Consumer、Predicate、Function复合
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
死磕Lambda表达式(三):更简洁的Lambda的更多相关文章
- 死磕Lambda表达式(二):Lambda的使用
城市就是森林,每一个男人都是猎手,每一个女人都是陷阱.--<三体> 在哪使用Lambda表达式? 在上一篇文章(传送门)中介绍了Lambda表达式的基本语法,其中的举了一个Lambda表达 ...
- 【转】Linq表达式、Lambda表达式你更喜欢哪个?
[转]Linq表达式.Lambda表达式你更喜欢哪个? 什么是Linq表达式?什么是Lambda表达式? 如图: 由此可见Linq表达式和Lambda表达式并没有什么可比性. 那与Lambda表达式相 ...
- Lambda 表达式,Java中应用Lambda 表达式
一.Lambda 表达式 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. 链接:知乎 先举一个普通的 Python 例 ...
- Linq表达式、Lambda表达式你更喜欢哪个?
什么是Linq表达式?什么是Lambda表达式? 如图: 由此可见Linq表达式和Lambda表达式并没有什么可比性. 那与Lambda表达式相关的整条语句称作什么呢?在微软并没有给出官方的命名,在& ...
- MySQL强人“锁”难《死磕MySQL系列 三》
系列文章 一.原来一条select语句在MySQL是这样执行的<死磕MySQL系列 一> 二.一生挚友redo log.binlog<死磕MySQL系列 二> 前言 最近数据库 ...
- C# Lambda表达式详解,及Lambda表达式树的创建
最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介 ...
- C#中Lambda表达式类型Expression不接受lambda函数
在EF Core中我们经常会用System.Linq.Expressions系统命名空间的Expression<TDelegate>类型来作为EF Core的查询条件,比如: using ...
- Java中lambda表达式详解
原文地址:http://blog.laofu.online/2018/04/20/java-lambda/ 为什么使用lambda 在java中我们很容易将一个变量赋值,比如int a =0;int ...
- JDK新特性-Lambda表达式的神操作
一.Lambda表达式的介绍 Lambda表达式是 Java8 中最重要的新功能之一.使用 Lambda 表达 式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看 起来更简洁易懂.Lambd ...
随机推荐
- Oracle 10G 服务端的安装
安装依赖包yum -y install binutils compat-libstdc++-33 compat-libstdc++-33.i686 elfutils-libelf elfutils-l ...
- Django的乐观锁与悲观锁实现
1) 事务概念 一组mysql语句,要么执行,要么全不不执行. 2) mysql事务隔离级别 Read Committed(读取提交内容) 如果是Django2.0以下的版本,需要去修改到 ...
- Nginx笔记总结十四: nginx反向代理,用内网域名转发
user www www; worker_processes ; error_log logs/error.log; pid logs/nginx.pid; worker_rlimit_nofile ...
- [转]cookie 和 session
原文:https://github.com/alsotang/node-lessons/tree/master/lesson16 读别人源码教程的时候,看到了这个,觉得写的很透彻,转. 众所周知,HT ...
- WordPress调用page页面内容方法
WordPress调用page页面内容方法,有时候在特殊条件下,原有的wordpress页面获取内容代码不能正常使用,这个时候不能通过wordpress自带的模板标签输出,就需要改变下方式,通过PHP ...
- btrace简单使用
基本安装 在github上btrace项目的release下 下载最新的btracehttps://github.com/btraceio/btrace/releases 解压完后,将btrace的b ...
- Java Servlet和Java Filter简介
一:简介servlet 1.什么是Servlet? Servlet可以通过多种方式进行描述,具体取决于上下文: (1)Servlet是一种用于创建web应用程序的技术 (2)Servlet是一个API ...
- iOS多线程开发之GCD(死锁篇)
上篇和中篇讲解了什么是GCD,如何使用GCD,这篇文章将讲解使用GCD中将遇到的死锁问题.有兴趣的朋友可以回顾<iOS多线程开发之GCD(上篇)>和<iOS多线程开发之GCD(中篇) ...
- Liferay7 Intellij IDEA 开发环境搭建
一.安装Liferay插件 安装过程不在赘述,推荐两种安装方式: 通过Intellij插件市场安装 通过下载插件zip包安装 安装完成后,在项目板块中点鼠标右键,会出现Liferay菜单. 二.安装L ...
- python爬虫所遇问题列举
1.通过python socket库来构造请求报文,向服务器发送图片请求时 (1)图片在浏览器请求头中的remote address信息跟通过python socket输出远程连接地址和端口号不一致 ...