Java8 Lambda表达式入门
可能很多人都听说过java8的新特性----Lambada表达式,但可能很多人都不知道Lambda表达式到底有什么用,下面我带大家理解一下Lambada表达式。
在平时的编程中,我们常常会用到匿名内部类,见下面代码:
package 示例;
import static org.junit.Assert.*;//
import org.junit.Test;
public class LambdaTest {
@Test
public void testOld1() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("原始方法使用匿名内部类");
}
}).start();
}
}
上述代码运用到了匿名内部类,但你们有没有发现,接口名和方法名在这段代码逻辑中是固定的,也就是说我们通过实现Runnable接口就必定实现父类接口中的run方法。写一万次上述代码,只有run方法内部的算法逻辑是改变的。
java8也就引入了一个新特性-----Lambda表达式
package 示例;
import static org.junit.Assert.*;
import org.junit.Test;
public class LambdaTest {
@Test
public void testNew1(){
/*此处用Lambda表达式,省略了接口名“new Runnable(){}”,以及接口中需要实现的方法名,以及修饰方法关键字(public void),只留下run方法用来传参数的“()”。因为run方法没有参数,所以括号中什么也没有 (这里的圆括号就是run方法的括号,只是省略了方法名)*/
new Thread(()->System.out.println("Lambda表达式")).start();
}
}
在上面的代码中,我们用Lambda表达式代替了传统的匿名内部类形式的Java代码,Lambda表达式如下:
()->System.out.println("Lambda表达式")
被替换的传统代码如下:
new Runnable(
public void run(){
System.out.println("匿名内部类");
}
)
(一)我们现在来看看为什么可以省略这些东西呢
(1)为什么可以省略接口名:
因为在Lambda表达式外面有new Thread()。而我们根据多线程的学习知道,Thread类的构造器如果只传入一个参数,那必定是Runnable接口实现类的实例。
public Thread(Runnable target)
所以编译器在编译的时候,是可以推断出来我们后面匿名内部类实现的接口是什么(Lambada表达式就是匿名内部类的精简写法),因此Lambda表达式将接口名省略。
(2)为什么可以省略接口中的方法名
通过上面我们知道了,编译器可以推导匿名内部类实现的接口名。那Runnable接口中只有一个抽象方法,因此编译器同样可以推导出实现类中的方法名。
(二)Lambda表达式的具体语法
语法:(参数列表)->{函数体};
注:Lambda表达式省略了匿名内部类的接口名、和方法名,目的就是让我们专注于接口方法的实现部分。
(1)参数列表规则
如果没有参数,直接用“()”表示。()不能省略。
如果只有一个参数,并且参数写了类型,则一定要加()
如果只写了一个参数,并且参数不写类型,那么这个参数外面不用加“()”。
- 如果有两个或多个参数,则“()”必须写。
(2)函数体规则
- 如果函数体只有一行,那么可以省略“{}”。
- 如果函数体有多行,则“{}”不能省略。
- 如果函数体有多行,并且该函数有返回值,则不能省略“return”关键字。
- 如果函数体是一行,并且函数有返回值,则必须省略“return”关键字(由编译器自己推导返回类型)
java8引入Lambda表达式的唯一目的就是简化函数式接口的使用。(暂时可以理解为简化匿名内部类的使用)
(三)Lambda表达式异常处理
- Lambda表达式产生的异常在函数体中try-catch。
- 在接口的抽象方法定义时,声明抛出异常。
(四)Lambda表达式使用场景(局限性)
由上面的的学习可知,Lambda表达式实际上就是匿名内部类的一种精简写法。在编译时还是会被推导为匿名内部类,说白了Lambda表达式就是一种“语法糖”。根据Lambda表达式省略接口名与方法名的原理可知,只有在编译器自身能够推导出匿名内部类实现的接口时,才能使用Lambda表达式。在能够推导出接口后,必须满足接口中只有一个抽象方法才能运用Lambda表达式。
补充说明:在Java中,通常将只有一个抽象方法的接口称为函数式接口,我们可以在接口上添加“@FunctionalInterface”标签,表明这是一个函数式接口。
总结
Java8新增的这一特性唯一的目的就是简化函数式接口的使用,它本身不是一个新的语法知识,底层实际上还是匿名内部类,所以学会灵活使用Lambda表达式,可以提高代码的开发效率,但在后期维护中降低了代码的可读性,博友们可以尝试一下这种“语法糖”。
下面是博主的其他文章,喜欢的博友点个关注,感谢您的支持。
JDK8以前匿名内部类访问局部变量为什么必须用final修饰
Validate插件的自定义表单校验入门(结合Ajax实现用户名的数据库查重)
Java8 Lambda表达式入门的更多相关文章
- java8 Lambda表达式的新手上车指南(1)
背景 java9的一再推迟发布,似乎让我们恍然想起离发布java8已经过去了三年之久,java8应该算的上java语言在历代版本中变化最大的一个版本了,最大的新特性应该算得上是增加了lambda表达式 ...
- java8 Lambda表达式的新手上车指南(1)--基础语法和函数式接口
背景 java9的一再推迟发布,似乎让我们恍然想起离发布java8已经过去了三年之久,java8应该算的上java语言在历代版本中变化最大的一个版本了,最大的新特性应该算得上是增加了lambda表达式 ...
- 函数式编程/lambda表达式入门
函数式编程/lambda表达式入门 本篇主要讲解 lambda表达式的入门,涉及为什么使用函数式编程,以及jdk8提供的函数式接口 和 接口的默认方法 等等 1.什么是命令式编程 命令式编程就是我们去 ...
- Java Lambda表达式入门
Java Lambda表达式入门 http://blog.csdn.net/renfufei/article/details/24600507 Java 8十个lambda表达式案例 http://w ...
- Java学习笔记--Java8 Lambda表达式
Java Lambda表达式入门:http://blog.csdn.net/renfufei/article/details/24600507 lambda内容的介绍:http://swiftlet. ...
- Java8 Lambda表达式详解手册及实例
先贩卖一下焦虑,Java8发于2014年3月18日,距离现在已经快6年了,如果你对Java8的新特性还没有应用,甚至还一无所知,那你真得关注公众号"程序新视界",好好系列的学习一下 ...
- Java8 Lambda表达式(一)
目录 一.应用场景引入 优化一:使用策略模式 优化二:使用匿名内部类 优化三:使用Lambda表达式 优化四:使用Stream API 二.Lambda运算符和对应语法 语法格式 Lambda表达式需 ...
- Java8 Lambda表达式、函数式接口和方法引用
目录 Java8 Lambda表达式和函数式接口 Lambda表达式 Lambda的使用 函数式接口FunctionalInterface Java内置四大核心函数式接口 方法引用 构造器引用 Jav ...
- java8之lambda表达式入门
1.基本介绍 lambda表达式,即带有参数的表达式,为了更清晰地理解lambda表达式,先上代码: 1.1 两种方式的对比 1.1.1 方式1-匿名内部类 class Student{ privat ...
- java8 快速入门 lambda表达式 Java8 lambda表达式10个示例
本文由 ImportNew - lemeilleur 翻译自 javarevisited.欢迎加入翻译小组.转载请见文末要求. Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发 ...
随机推荐
- Push failed idea将项目发布到gitHub失败
此时需要点击VCS --> inport into version..-->create git ...重新生成仓库
- 开始学习web-sql注入
web内容多且杂,不知道怎么下手开始学,那就先从sql注入开始学吧 目前只在b站上找了一些课程,还有ctfwiki作为参考 链接贴在下面: ctfwiki https://www.bilibili.c ...
- 重新整理数据结构与算法(c#)—— 二叉树排序树补删除节点[二十二]
前言 续前一章. 正文 删除节点规则: 1.假如删除的是叶子节点,让他的父节点,断开和它的联系. 2.如果删除节点右左子树或者右子树的话,那么应该这样. 如果删除节点是它的父节点的左节点,而删除节点有 ...
- leetcode:763. 划分字母区间
763. 划分字母区间 字符串 S 由小写字母组成.我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段.返回一个表示每个字符串片段的长度的列表. 示例 1: 输入: S = & ...
- python3中os.renames()和os.rename()区别
renames源码:def renames(old, new): head, tail = path.split(new) # 作用是分割为两部分,head为路径,tail为文件名: if head ...
- 集群部署时的分布式 session 如何实现?
面试官心理分析 面试官问了你一堆 dubbo 是怎么玩儿的,你会玩儿 dubbo 就可以把单块系统弄成分布式系统,然后分布式之后接踵而来的就是一堆问题,最大的问题就是分布式事务.接口幂等性.分布式锁, ...
- hibernate4升级5带来的一些参数变化
public String hqlToHibernate5(String hql) { String[] tmp = hql.split(" "); String hqlTmp = ...
- stm32串口晶振不对输出乱码+汇承HC-14lora模块
最近要用到一个lora无线透传模块,然后就先用两个32开发板(用的STM32F103C8T6)试试简单的收发数据.结果,第一步串口发送一句话就寄了,我串口打印了"hi",结果出现了 ...
- Hologres如何支持超高基数UV计算(基于roaringbitmap实现)
简介: 本文将会介绍Hologres基于roaringbitmap实现超高基数的UV计算 RoaringBitmap是一种压缩位图索引,RoaringBitmap自身的数据压缩和去重特性十分适合对于大 ...
- Dubbo 跨语言调用神兽:dubbo-go-pixiu
简介: Pixiu 是基于 Dubbogo 的云原生.高性能.可扩展的微服务 API 网关.作为一款网关产品,Pixiu 帮助用户轻松创建.发布.维护.监控和保护任意规模的 API ,接受和处理成千上 ...