jdk1.8新特性之Lambda表达式

本文探讨了Java 8中的Lambda表达式,它是该版本的重大更新之一,与C#的Lambda表达式进行对比。Lambda表达式提供了一种更简洁、可读的编写代码方式,尤其在处理集合操作时。Java的Lambda表达式与函数式接口紧密相关,而C#的Lambda则使用=>运算符。虽然Lambda表达式使代码更紧凑,但Scala等语言已具备类似功能,未来的发展将决定它们在编程领域的地位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java8的两个重大改变,一个是Lambda表达式,另一个就是Stream API表达式。Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作,在新版的JPA【连接数据库】中,也已经加入了Stream
本次分享主要是Lambda表达式:

Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

1.C#的Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to”。语法如下:

(object argOne, object argTwo) => {; /*Your statement goes here*/}

函数体多于一条语句的可用大括号括起
类型
可以将此表达式分配给委托类型,如下所示:

delegate int del(int i);
del myDelegate=x=>{return x*x;};
int j = myDelegate(5); //j=25

创建表达式目录树类型:

using System.Linq.Expressions;
//...
Expression <del>=x=>x*x;

=> 运算符具有与赋值运算符 (=) 相同的优先级,并且是右结合运算符。
Lambda 用在基于方法的 LINQ 查询中,作为诸如 Where 和 Where 等标准查询运算符方法的参数
!!!!在 is 或 as 运算符的左侧不允许使用 Lambda。

下列规则适用于 Lambda 表达式中的变量范围:
1.捕获的变量将不会被作为垃圾回收,直至引用变量的委托超出范围为止。
2.在外部方法中看不到 Lambda 表达式内引入的变量。
3.Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。
4.Lambda 表达式中的返回语句不会导致封闭方法返回。
5.Lambda 表达式不能包含其目标位于所包含匿名函数主体外部或内部的 goto 语句、break 语句或 continue 语句。
6.Lambda表达式的本质是“匿名方法”,即当编译我们的程序代码时,“编译器”会自动将“Lambda表达式”转换为“匿名方法”,如下例:

string[] names={"agen","balen","coure","apple"};
string[] findNameA=Array.FindAll<string>(names,delegate(string v){return v.StartsWith("a");});
string[] findNameB=Array.FindAll<string>(names,v=>v.StartsWith("a"));

上面中两个FindAll方法的反编译代码如下:

string[] findNameA=Array.FindAll<string>(names,delegate(string v){return v.StartsWith("a");});
string[] findNameB=Array.FindAll<string>(names,delegate(string v){return v.StartsWith("a");});

从而可以知道“Lambda表达式”与“匿名方法”是可以划上等号的,只不过使用“Lambda表达式”输写代码看上去更直观漂亮
C#的Lambda表达式的语法格式:
参数列表 => 语句或语句块 [1]

2.Java的Lambda表达式

Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。下面这个例子就是使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读。
java中的Lambda表达式中引入的操作符及注意事项:
在这里插入图片描述
java中的Lambda表达式中 函数式接口
(1)什么是函数式接口?
函数接口:如果一个接口只有一个抽象方法,则该接口称之为函数式接口,函数式接口可以使用Lambad表达式,Lambda表达式会倍匹配到这个抽象方法上。

(2)如果我自己不知道该接口是否符合函数式接口怎么办?
如果分不清是否符合的话可以采用注解的方式来检测,@Functionallnterface 注解可以检测接口是否符合函数式接口

@Functionallnterface使用:


// 正确的函数式接口  
@FunctionalInterface  
public interface TestInterface {  
 
 
    // 抽象方法  
    public void sub();  
 
    // java.lang.Object中的方法不是抽象方法  
    public boolean equals(Object var1);  
 
    // default不是抽象方法  
    public default void defaultMethod(){  
 
    }  
 
    // static不是抽象方法  
    public static void staticMethod(){  
 
    }  
}  

常见的函数式接口:
在这里插入图片描述

使用lambda表达式和没有使用的区别

没有使用Lambda的老方法:

button.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent actionEvent){
        System.out.println("Action detected");
    }
});

使用Lambda:

button.addActionListener( actionEvent -> { 
    System.out.println("Action detected");
});

让我们来看一个更明显的例子。
不采用Lambda的老方法:

Runnable runnable1=new Runnable(){
@Override
public void run(){
    System.out.println("Running without Lambda");
}
};

使用Lambda:

Runnable runnable2=()->System.out.println("Running from Lambda");

正如你所看到的,使用Lambda表达式不仅让代码变的简单、而且可读、最重要的是代码量也随之减少很多。然而,在某种程度上,这些功能在Scala等这些JVM语言里已经被广泛使用。
一方面,如果Java继续围绕Lambda来发展和实现Scala都已经实现的功能,那么可能就不需要Scala了。另一方面,如果它只提供一些核心的功能,例如帮助匿名内部类,那么Scala和其他语言将会继续茁壮成长,并且有可能会凌驾于Java之上。其实这才是最好的结果,有竞争才有进步,其它语言继续发展和成长,并且无需担心是否会过时。

关于Stream API表达式我会在下篇文章进行详细分享,有兴趣的小伙伴可以关注一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值