文章目录
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 免费领取资料哦!
网友评论