Java-函数式编程(二)Lambda表达式

本文首发:
Java-函数式编程(二)Lambda表达式

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

认识lambda

1
2
3
4
5
6
7
8
public static void main(String[] args) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("匿名内部类的执行");
        }
    }).start();
}

  

设计匿名内部类的目的,就是为了方便程序猿将代码作为数据来传递。但是你会发现,这个对象看起来是很多余的,所以我们不想传入对象,只想传入行为。

1
2
3
new Thread(()->{
    System.out.println("lambda代替内部类");
}).start();

  

和实现某接口的对象不同,我们传入了一段代码块--一个没有名字的函数。->将参数和表达式主体分开,左边是参数,右边是方法体。

Lambda的不同形式

1
Runnable runnable =  ()-> System.out.println("hello world");

 

该Lambda表达式不包含参数(因为是空括号)。

1
2
3
4
5
6
interface Test{
        void oneParam(String name);
    }
 
Test test = s -> System.out.println("oneParam方法传递参数:"+s);
test.oneParam("我是传递的值");

  

控制台输出:
1
oneParam方法传递参数:我是传递的值

  

(lambda只能用于函数式接口),如果参数只包含一个参数,可以省略参数的括号。

1
2
3
4
5
6
interface Test2{
       int add(int a,int b);
 }
Test2 test2 = (x,y) -> x+y;
int add = test2.add(10, 10);
System.out.println(add);

控制台输出:
1
 

可以看到,我们在使用lambda的时候创建了一个函数x+yTest2对象不是表示两个数字的和,而是表示两个数字相加的代码。以上的代码中,参数类型都是由编译器自己推断的,同样,我们可以明确的声明参数类型:

1
2
3
4
5
6
interface Test3{
        long add(long a,long b);
    }
 
Test3 test3 = (long x,long y) -> x+y;
long add = test3.add(10, 10);

  

引用值的要求

Error:(25, 64) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量

1
2
3
4
String  name = "FantJ";
        Runnable runnable =  ()-> System.out.println("hello " +name);
        runnable.run();
hello FantJ

上面这段代码,Lambda可以引用非final变量这个属性你可以早已了解,但是你更需要知道,java8只是放松了这一语法的限制,但实际上要求该变量还是final。

Java-函数式编程(二)Lambda表达式Java-函数式编程(二)Lambda表达式

可以看到,不管name在使用lambda的前还是后做改动,lambda都会报错:表达式引用的本地变量必须是最终变量或实际上的最终变量,简单的,我们可以称他为既成事实上的final变量。所以,lambda也被称为闭包。

Lambda表达式类型

java中,所有方法都有返回类型,那lambda返回类型是什么呢。

是接口方法的返回类型。这一点前文有体现过。这里再详细解释下。

1
2
3
interface Test{
        void oneParam(String name);
}

拿这个例子来讲,oneParam方法表示一种行为:接受一个String,返回void。只要方法名和行为和Lambda表达式匹配即可完成调用。

注意:如果编译器猜不出参数和返回值的类型,则都将视为Object处理。

posted on   Java知音号  阅读(4634)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示