【Java 基础语法】详解 Java 的 Lambda 表达式

文章目录

2. Lambda 表达式的语法

4. Lamdba 表达式的使用

5.2 匿名内部类的变量捕获

5.3 Lambda 的变量捕获

6. Lambda 在集合中的使用

7. Lambda 表达式的优点和缺点

1. 介绍

Lambda 表达式是 JavaSE8 中的一个重要的新特性

Lambda 表达式允许你通过表达式来代替功能接口

Lambda 表达式和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体

Lambda 表达式可以看作是一个匿名函数,基于数学中的 λ 演算得名,也可以称其为闭包

Lambda 表达式允许把函数作为一个方法的参数

2. Lambda 表达式的语法

基本形式:Lambda 表达式由三部分组成:参数、->符号、方法体

(参数列表)->{

方法体}

补充:

Lambda 表达式的参数可以是零个或多个

参数的类型可以明确声明,也可以不声明,由 JVM 隐式的推断,例如 (int a) 和 (a) 效果相同

当参数只有一个,且类型可推导时,可以省略括号,例如 (a) 与 a 效果相同

如果 Lambda 表达式的方法体只有一条语句时,可以省略花括号

如果 Lambda 表达式的方法体只有一条语句,且为返回值的时候,可以省略 return

代码示例:

// 不需要参数,返回值为 2()->2// 接收一个参数(数字类型),返回值为其2倍的值x->2*x// 接收两个参数(数字类型),并返回它们的和(x,y)->x+y// 接收两个 int 类型参数,返回它们的乘积(intx,inty)->x*y// 接收一个 String 对象,并在控制台打印(Strings)->System.out.println(s)

3. 函数接口

如果一个接口中有且只有一个 abstract 方法,称这样的接口为单接口。从 JDK8 开始,Java 使用 Lambda 表达式,并将单接口称为函数接口

注意:

@FunctionInterface

示例代码:

@functionInterfaceinterface A{

void test();}

4. Lamdba 表达式的使用

接下来为大家演示 Lambda 表达式的使用

// 无返回值无参数 @FunctionalInterfaceinterfaceNoParameterNoReturn{

void test();}// 无返回值一个参数 @FunctionalInterfaceinterfaceOneParameterNoReturn{

void test(int a);}// 无返回值多个参数 @FunctionalInterfaceinterfaceMoreParameterNoReturn{

void test(int a,int b);}// 有返回值无参数 @FunctionalInterfaceinterfaceNoParameterReturn{

int test();}// 有返回值一个参数 @FunctionalInterfaceinterfaceOneParameterReturn{

int test(int a);}// 有返回值多参数 @FunctionalInterfaceinterfaceMoreParameterReturn{

int test(int a,int b);}publicclassTestDemo{

public static void main(String[] args) {

NoParameterNoReturnnoParameterNoReturn=()->{

System.out.println("无参数无返回值");};noParameterNoReturn.test();OneParameterNoReturnoneParameterNoReturn=(inta)->{

System.out.println("无参数一个返回值:"+a);};oneParameterNoReturn.test(10);MoreParameterNoReturnmoreParameterNoReturn=(inta,intb)->{

System.out.println("无返回值多个参数:"+a+" "+b);};moreParameterNoReturn.test(20,30);NoParameterReturnnoParameterReturn=()->{

System.out.println("有返回值无参数!");return40;};//接收函数的返回值 intret=noParameterReturn.test();System.out.println(ret);OneParameterReturnoneParameterReturn=(inta)->{

System.out.println("有返回值有参数!");returna;};ret=oneParameterReturn.test(50);System.out.println(ret);MoreParameterReturnmoreParameterReturn=(inta,intb)->{

System.out.println("有返回值多个参数!");returna+b;};ret=moreParameterReturn.test(60,70);System.out.println(ret);}}

5. 变量捕获

5.1 介绍

Java 中的局部类和匿名类都存在变量捕获

只有理解了什么是变量捕获之后,我们才能更好地理解 Lambda 表达式的作用域,因为 Lambda 表达式也存在变量捕获。

5.2 匿名内部类的变量捕获

classA{

public void func(){

System.out.println("func()");}}publicclassTestDemo{

public static void main(String[] args) {

inta=100;newTest(){

@Override public void func() {

System.out.println("我是内部类,且重写了func这个方法!");System.out.println("我是捕获到变量 a == "+a+" 我是一个常量,或者是一个没有改变过值的变量!");}};}}

上述代码中的变量 a 就是捕获变量,这个变量要么是被 final 修饰,要么就要保证此变量在匿名内部类中使用时没有被修改,如果修改就会编译出错

5.3 Lambda 的变量捕获

在 Lambda 中也可以进行变量捕获

@FunctionalInterfaceinterface A {

void test();}public static void main(String[] args) {

inta=10;NoParameterNoReturnnoParameterNoReturn=()->{

// a = 99; 如果修改a,则会报错 System.out.println("捕获变量:"+a);};noParameterNoReturn.test();}

6. Lambda 在集合中的使用

为了能够让 Lambda 和 Java 的集合类集更好的一起使用,集合当中也新增了部分接口,以便与 Lambda 表达式对接

对应的接口新增的方法

CollectionremoveIf() 、 spliterator() 、 stream() 、 parallelStream() 、 forEach()

ListreplaceAll() 、 sort()

MapgetDefault() 、 forEach() 、 replaceAll() 、 putIfAbsent() 、 remove() 、 replace() 、 computeIfAbsent() 、 computeIfPresent() 、 compute() 、 merge()

补充:

Collection 的 forEach() 方法是从接口 java.lang.Interable 继承的

6.1 Collection 接口

使用 forEach() 方法进行演示

forEach() 源码:

代码示例:使用匿名内部类

publicclass TestDemo{

publicstaticvoidmain(String[]args){

List<String>list=newArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.forEach(newConsumer<String>(){

@Overridepublicvoidaccept(Strings){

System.out.print(s+" ");}});}}// 结果为:aaa bbb ccc

代码示例:使用 Lambda

publicclass TestDemo{

publicstaticvoidmain(String[]args){

List<String>list=newArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.forEach(s->System.out.print(s+" "));}}// 结果为:aaa bbb ccc

6.2 List 接口

使用 sort() 方法进行演示

sort() 源码:

代码示例:使用匿名内部类

publicclassTestDemo{

public static void main(String[] args) {

List<String>list=newArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.sort(newComparator<String>(){

@Overridepublicintcompare(Stringo1,Stringo2){

returno1.compareTo(o2);}});System.out.println(list);}}// 结果为:[aaa, bbb, ccc]

代码示例:使用 Lambda

publicclass TestDemo{

publicstaticvoidmain(String[]args){

List<String>list=newArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.sort((Stringo1,Stringo2)->o1.compareTo(o2));System.out.println(list);}}// 结果为:[aaa, bbb, ccc]

6.3 Map 接口

使用 HashMap 的 forEach() 方法进行演示

HashMap 的 forEach() 源码:

代码示例:使用匿名内部类

publicclassTestDemo{

public static void main(String[] args) {

Map<Integer,String>map=newHashMap<>();map.put(1,"aaa");map.put(2,"222");map.put(3,"333");map.forEach(newBiConsumer<Integer,String>(){

@Overridepublicvoidaccept(Integerinteger,Strings){

System.out.println("Key="+integer+" Value="+s);}});}}/** 结果为:

Key=1 Value=aaa

Key=2 Value=222

Key=3 Value=333

*/

代码示例:使用 Lambda

publicclassTestDemo{

public static void main(String[] args) {

Map<Integer,String>map=newHashMap<>();map.put(1,"aaa");map.put(2,"222");map.put(3,"333");map.forEach((Integerinteger,Strings)->System.out.println("Key="+integer+" Value="+s));}}/** 结果为:

Key=1 Value=aaa

Key=2 Value=222

Key=3 Value=333

*/

7. Lambda 表达式的优点和缺点

优点:

代码简洁,开发迅速

方便函数式编程

容易进行并行计算

Java 引入 Lambda,改善了集合操作

缺点:

代码可读性变差

在非并行计算中,很多计算未必有传统 for 循环性能高

如果看完的小伙伴有兴趣了解更多的话,欢迎添加vx小助手:SOSOXWV  免费领取资料哦!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容