Lambda表达式的简单总结

本文围绕Java的lambda表达式展开,介绍了函数式接口,它是lambda表达式实例化对象简化的基础。阐述了lambda表达式的语法规则、应用场景,对比传统方法展示其简化效果,还提及访问外部变量的规则。此外,介绍了方法引用,它是对lambda表达式的进一步简化,有四种类型。

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

最近在学习lambda表达式的时候,由于对书本中内容的理解处了些偏差,导致学习上绕了弯路,所以一次性把lambda表达式的部分进行整理
但需要了解的是,lambda表达式及其相关部分并未涉及到新技术或编程思想,其不过只是对于编程工作简化的“语法糖”而已

一、函数式接口

函数式接口的本质依旧是接口,但其较普通接口接口而言,函数式接口限定为内部有且只有一个抽象方法。lambda表达式就是对此类接口实例化对象过程进行简化。
而且,出于编程过程的严谨性,建议对自定义函数式接口增加@FunctionalInterface的注解

二、lambda表达式

首先来看lambda表达式的语法规则:

	(参数列表) -> {lambda方法体}

其中,参数列表的括号、参数类型、方法体的大括号、方法体返回值这四部分均可视情况进行简化省略

lambda表达式的使用必须建立在对于相应函数式接口的定义的依赖上。lambda表达式的参数列表部分,是对函数式接口内部抽象方法的实参输入,而右侧的方法体是对抽象方法的具体实现代码。

而lambda的使用场景是在需要函数式接口的实现类的匿名实例对象时,从下面一个例子具体分析:

1> lambda表达式应用场景
@FunctionalInterface
public interface lambdatest{
	int test(int a){
	}
}
class Ltest{
	public static void main(String[] args) {
	//略
    	function(x,lambdatest A);
    }
	
}
2> 传统方法

使用场景为function方法需要接口lambdatest的实现类的实例对象,若未使用lambda表达式,则应该写为

class Ltest{
	public static void main(String[] args) {
	//略
    	function(x,new lambdatest(){
					int test(int a){
						System.out.println(a);
					}
		});
    }
}
3> lambda表达式简化后

在使用lambda表达式简化后,代码可写为

class Ltest{
	public static void main(String[] args) {
	//略
    	function(x,(int a) -> System.out.println(a));
    }
}

4> 对于源码阅读后的简单总结

此部分主要参考自衣舞晨风的文章,其中涉及到Java字节码的阅读,自己也并不能很好理解,只能对结论进行整理
简单地说,代码的等效执行逻辑为

class Ltest{
	//function方法定义
	public static void function(int a,lambdatest A) {
    	A.test(a);
    }
	
	//主函数
    public static void main(String[] args) {
    	//略
        function(x,new LTest$$Lambda$1());
    }

	//私有静态函数
    private static void lambda$main$0(String x) {
        System.out.println(x);
    }
	
	//内部类
    static final class LTest$$Lambda$1 implements lambdatest {
        public void test(Object obj) {
            LTest.lambda$main$0((int) obj);
        }
        private LTest$$Lambda$1() {
        }
    }
}

总的来看,整个编译过程如下:

  1. 在类编译时,会生成一个私有静态方法+一个内部类;
  2. 在内部类中实现了函数式接口,在实现接口的方法中,会调用编译器生成的静态方法;
  3. 在使用lambda表达式的地方,通过传递内部类实例,来调用函数式接口方法。
5> Lambda表达式访问其外部变量

以下内容整理自消失er的文章

  1. 可访问 static 修饰的成员变量,如果是 final static 修饰,不可再次赋值,只有 static 修饰可再次赋值;
  2. 可访问表达式外层的 final 局部变量(不用声明为 final,隐性具有 final 语义),不可再次赋值。

三、方法引用

方法引用是对lambda表达式的进一步简化,作用是定位某个静态方法或者实例方法,从而传递该方法实现函数式接口匿名实例对象,其语法形式为:

A::B
其中,A为类名或实例名,B为方法名称

主要有四种类型:

1.类名::静态方法名
2.对象::实例方法名
3.类名::实例方法名
4.类名::new

1> 类名::静态方法名

System.out::println等价于x->System.out.println(x)

2> 对象::实例方法名

Math::pow等价于(x,y)->Math.pow(x,y)

3> 类名::实例方法名

String::compareToIgnoreCase等价于(x,y)->x.compareToIgnoreCase(y)

4> 类名::new (即构造器引用)

int[]::new等价于x->new int[x]
构造器引用会传递以定位的构造方法实现抽象方法的函数式接口实例对象,在调用该实例对象的抽象方法(已被实现)时,结果是创建该构造器原属类的实例对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值