Lambda表达式

本文介绍了Java中的Lambda表达式,它在JDK1.8中引入,简化了匿名内部类的使用。Lambda表达式可以视为函数式接口的实例,允许一行代码实现特定功能。文中通过示例展示了Lambda表达式的使用,如`()->System.out.println(HelloLambda!)`,并与匿名内部类进行对比。此外,还讲解了函数式接口的定义,即接口内只有一个抽象方法,并讨论了默认方法的存在原因。最后,文章演示了如何使用Lambda表达式和方法引用,并提供了App类的例子,展示了Lambda在实际代码中的应用。

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

首先我们先了解下 Lambda 表达式名字的由来。实际上这个名字来自微积分数学中的 λ,其涵义是声明为了表达一个函数具体需要什么。更确切的说,它描述了一个数学逻辑系统,通过变量结合和替换来表达计算。所以,基本上我们有 0-n 个输入参数和一个返回值。而在编程语言中,我们也提供了无返回值的 void 支持。

通俗易懂的来讲就是函数式编程,熟悉Python的人对Lambda表达式定然十分了解了,而在java中确实在jdk1.8的时候才推出的。放到java中对比的话,就可以把Lambda表达式看作是java中的匿名内部类。如下

        //匿名内部类写法
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello 匿名内部类!");
            }
        }).start();

        //Lambda写法
        new Thread(() -> System.out.println("Hello Lambda!")).start();

使用起来很简单,也很简洁,匿名内部类需要6行代码才能完成的事儿,Lambda只需要1行就可以完成。

总的来说,Lambda就是java的语法糖!!!

Lambda也被人叫做函数式编程,那么自然就少不了函数式接口(从上边代码示例中也不难发现就是一个简化了的匿名内部类),那么怎么定义一个函数式接口呢?说来也简单,就是一个接口中有且只有一个抽象方法,如Runnable接口中只有一个run方法。

@FunctionalInterface
public interface Runnable {

    public abstract void run();
}

其中@FunctionInterface并无实际作用,他只是标识了这个接口是一个函数式接口。那么为什么要强调是抽象方法呢?接口中不是只有抽象方法嘛?

interface Test{
    static void t1(){
        
    }
    
    default void t2(){
        
    }
}

可以看到其实在jdk1.8的时候接口中是允许存在静态方法以及default修饰的方法的。default方法存在原因很简单,在jdk1.8中出现了lambda表达式,自然java类库也是采用了这种方式的,那么截止到1.8之前java的类库已经是非常庞大了,如果将那些相关类库一一进行修改对java开发人员将会是极大的挑战,而且也会为用户造成极大的困扰,于是default方法应运而生。

如何定义一个函数式接口?

很简单,如前边提到的一样,一个接口中有且只有一个抽象方法,那么这个接口就是一个函数式接口。

@FunctionalInterface
interface TestFunction {
    int apply(int a, int b);
}

该接口只有一个方法apply,参数一个两个int类型的a和b,返回值类型为int。那么怎么使用呢?

public class App {

    int a;
    int b;

    public App(int a, int b) {
        this.a = a;
        this.b = b;
    }

    public static App build(int a, int b) {
        return new App(a, b);
    }

    public int sum(TestFunction fun) {
        return fun.apply(a, b);
    }

    public static void main(String[] args) {
        System.out.println(App.build(100, 6).sum((x, y) -> x + y));
    }
}

App类中有两个属性a和b,为了简化这里采用了静态工厂的方式创建对象也就是build方法。其中的sum方法就是lambda表达式的一种用法。入参是一个函数式接口,并且内部调用了函数式接口唯一的抽象方法。使用方法如main方法中所示

App.build(100, 6).sum((x, y) -> x + y)

调用sum方法之前的不难理解就是通过静态工厂创建了一个对象,而sum方法中的函数体就有点耐人寻味了。

其中x和y分别表示函数接口TestFunction.apply方法中的参数a和b。-> 在我看开来就是一个符号,没有什么实际意义,而且在不同的语言中使用的也是不同的,这个符号后边就是x+y,这个就是apply方法所要执行的内容,也可以将它看成是apply的方法体。

上诉代码中的调用还有一个简化写法,如下

App.build(100, 6).sum(Integer::sum)

其中Integer::sum表示的就是Integer的静态方法sum(),也就是Integer.sum(a,b)。这种写法称为方法引用。方法引用可以是静态方法引用也可以是普通方法引用,当然还可以是构造方法引用,也叫构造引用。

        //普通方法引用
        App app = App.build(10, 20);
        app.sum(app::add);

        class Test {
            double result;

            public Test(int result) {
                this.result = result;
            }
        }
        //构造引用
        List<Test> tests = Stream.of(1, 2, 3).map(Test::new).toList();

构造引用采用了Stream的Api作为示例,Stream是jdk1.8提供的处理数据的流,整个API都是使用函数式编程,如果使用得当会简化开发。

lambda表达式的用法就记录到这里。下一节介绍jdk提供的函数式接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值