java_Lambda表达式

目录

1. 背景

1.1 Lambda表达式的语法

1.2 函数式接口

2. Lambda表达式的基本使用

2.1 语法精简

3. 变量捕获

3.1 匿名内部类

3.2 匿名内部类的变量捕获

3.3 Lambda的变量捕获

4. Lambda在集合当中的使用

4.1 Collection接口

foreach()方法演示:

4.2 List接口

4.3 Map接口

5. 总结

完!!!


1. 背景

Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许通过表达式来代替功能接口。lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。Lambda表达式,基于数学中的λ得名,也可称为闭包(Closure)。

1.1 Lambda表达式的语法

基本语法:(parameters) -> expression(parameters) -> {statements;}

Lambda表达式由三部分组成:

        1.parameters:类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明,也可以不生命而由JVM隐含的进行推断。另外,当只有一个推断类型的时候,可以省略掉圆括号。

        2. -> 可以理解为“被用于”的意思

        3.方法体:可以是表达式,也可以是代码块,是函数式接口里方法的实现。代码块可返回一个值,或者什么都不返回,这里的代码块等同于方法的方法体。如果是表达式,也可以返回一个值,或者什么都不返回。

1.2 函数式接口

要了解Lambda表达式,首先需要了解什么是函数式接口,函数式接口定义一个接口有且只有一个抽象方法

注意:

        1.如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口

        2.如果我们在某个接口上声明了@FunctionalInterface注解,那么编译器就会按照函数式接口的定义来要求该接口,这样如果该接口中有两个抽象方法,程序编译就会报错的。所以,从某种意义上来说,只要你保证你的接口中只有一个抽象方法,你可以不加上这个注解,加上就会自动进行检测的。

定义方式:

如果多一个抽象方法,注解就会报错

但还有一种情况,是在JDK1.8中的新特性,即default默认方法可以有具体的实现:

2. Lambda表达式的基本使用

我们先可以用前面的一个例子给展现一下Lambda表达式的使用:

在我前面的文章:java数据结构_Map和Set_面试题_9.4-优快云博客中,有一道面试题是求出使用频率前K个单词,其中有一段代码如下:

是建立一个小根堆,但要指定其比较方式,所以自动生成了一段内部类来指定,这一段内部类就可以使用Lambda表达式来代替:

怎么样,是不是初步有了一些认识,接下来我们进行Lambda表达式的基本使用

首先,我们先准备好几个接口:

我们在上面提过,Lambda可以理解为:Lambda就算匿名内部类的简化,实际上是创建了一个类,实现了接口,重写了接口的方法。

如果不使用Lambda表达式的时候的调用方式:

如果使用Lambda表达式:

其他情况下的具体使用如下图:

2.1 语法精简

        1.参数类型可以省略,如果需要省略,每个参数的类型都有省略。

        2.参数的小括号里面只有一个参数,那么小括号可以省略。

        3.如果方法体当中只有一句代码,则大括号可以省略

        4.如果方法体中只有一条语句,而且是return语句,那么大括号可以省略,且去掉return关键字。

示例代码:

3. 变量捕获

Lambda表达式中存在变量捕获,了解了变量捕获之后,才能更好的理解Lambda表达式的作用域。Java当中的匿名类,回存在变量捕获。

3.1 匿名内部类

匿名内部类就算没有名字的内部类。我们这里只是为了说明变量捕获,所以,匿名内部类只需简单的只用即可。

示例如下:

上述代码中的main函数当中,就算一个匿名内部类的简单使用。

3.2 匿名内部类的变量捕获

上述代码中,变量a就算捕获的变量。注意:这个变量要么是被final修饰的,如果不是被final修饰的,就一定要保证该变量在被使用之前,没有被修改。

如下代码就算一个错误的代码:此时编译器会直接编译报错!

3.3 Lambda的变量捕获

在Lambda中,也可以进行变量的捕获,代码如下:

注意,此时捕获的变量a同样的不能被修改的

4. Lambda在集合当中的使用

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

以上方法的作用可自行查看java帮助手册,这里进行一些方法的使用示例。

注意:Collection的forEach方法是从接口java.lang.Iterable拿过来的

4.1 Collection接口

foreach()方法演示:

该方法在接口Iterable当中,原型如下:

该方法表示:对容器中的每个元素执行action指定的动作。

示例如下:

结果如下:

也可以修改为如下代码,使用lambda表达式:

可见,结果是相同的。

4.2 List接口

sort()方法的演示:

sort方法源码:该方法根据c语言指定的比较规则对容器元素进行排序。

使用示例:

进行lambda表达式的修改:

方法体中只有一句代码,可以不用加花括弧。

4.3 Map接口

HashMap的forEach()

源码如下:

作用是对Map重点每个映射执行action指定的操作。

代码示例:

改写为lambda表达式:

5. 总结

Lambda表达式的优点很明显,在代码层次上来说,使得代码变的非常整洁。缺点也很明显,代码易读性差。

优点:

        1.代码简洁,开发迅速

        2.方便函数式编程

        3.非常容易进行并行计算

缺点:

        1.代码可读性变差

        2.在非并行计算中,很多计算未必有传统的for性能高

        3..不容易进行调试

完!!!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值