Java lambda表达式

111 阅读4分钟

什么是lambda表达式

Java lambda表达式是Java 8引入的一种新的语法特性,用于简化函数式编程的代码编写。Lambda表达式可以看作是一种匿名函数,它可以作为参数传递给方法或存储在变量中

上面是较为官方的回答,简单来说就是将函数作为函数的参数,是对匿名内部类的一个优化。

在JavaScript中,python中函数都可以作为参数使用,但是在Java中,要想在函数内部使用函数,必须先将该函数的所属的对象传入,这就非常麻烦。Java程序员就开始吐槽为什么其他语言可以将函数如此灵活使用,终于在jdk8中,加入了lambda表达式。

lambda表达式语法

我们使用一个线程创建的例子来说明

不使用lambda表达式

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的逻辑
    }
}

public class Main {
    public static void main(String[] args) {
        Runnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

不使用lambda表达式之前,我们需要去实现Runnable接口并且将实现类实例对象传入构造函数。

当然这段代码我们可以实现使用匿名内部类优化

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // 线程执行的逻辑
            }
        });
        thread.start();
    }
}

这里建议没有了解过内部类的先去了解一下,这里不做过多概述。

使用lambda表达式

public class Main {
    public static void main(String[] args) {
        Runnable myRunnable = () -> {
            // 线程执行的逻辑
        };
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

Lambda表达式的基本语法如下:
(parameter1, parameter2, ..., parameterN) -> { // 方法体
}

其中,参数列表(parameter1, parameter2, ..., parameterN)是可选的,如果没有参数,则可以省略括号;方法体可以是一个表达式或一个代码块。

lambda是一个匿名函数,编译器会根据上下文来判断该函数是哪个接口中方法,并且自动的创建内部类和实例对象。也就是说不用我们自行的创建匿名内部类的,所以lambda表达式的本质其实就是对匿名内部类的优化。

函数式接口

lambda表达式离不开函数式接口的支持。

函数式接口是Java 8中引入的一个概念,它是指只包含一个抽象方法的接口。函数式接口可以看作是一种约定,它告诉编译器这个接口的实现类应该被当作函数来对待。在函数式接口中,可以包含默认方法、静态方法和Object类的方法(如equals()和toString()),但只能有一个抽象方法。

简单来说,函数式接口就是只包含一个抽象方法的接口。

试想一下,如果我们的lambda表达式实现的接口实现类有多个方法,那么编译器怎么会知道我们实现的是哪个方法,所以要想书写lambda表达式,对应的接口必须只包含一个方法。

要创建一个函数式接口,需要遵循以下几个步骤:

  1. 定义接口:创建一个新的接口,并在接口中声明一个抽象方法。这个抽象方法将成为函数式接口的唯一抽象方法。
@FunctionalInterface
public interface MyFunctionalInterface {
    void myMethod();
}
  1. 添加@FunctionalInterface注解(可选):为了明确地告诉编译器这个接口是函数式接口,可以在接口上添加@FunctionalInterface注解。这个注解是可选的,但推荐使用,因为它可以帮助我们在编译时检查接口是否符合函数式接口的要求。
@FunctionalInterface
public interface MyFunctionalInterface {
    void myMethod();
}
  1. 添加默认方法(可选):函数式接口可以包含默认方法、静态方法和Object类的方法。如果需要在接口中添加一些默认的实现方法,可以在接口中定义这些方法。
@FunctionalInterface
public interface MyFunctionalInterface {
    void myMethod();
    
    default void myDefaultMethod() {
        // 默认方法的实现
    }
}
  1. 使用函数式接口:通过Lambda表达式或方法引用,可以创建函数式接口的实例,并调用其抽象方法。
MyFunctionalInterface myFunc = () -> {
    // 抽象方法的实现
};
myFunc.myMethod();

通过以上步骤,我们就可以创建一个函数式接口,并使用Lambda表达式来实现其抽象方法。