作为一个编程苦手,在浏览别人的代码时,时不时会遇见自己从来没见到过的语法。深究起来,大部分是语言在新版本引入的语法糖,于是我便有了将这些令我感到费解的语法汇总起来的想法,以便自己忘记时回来翻看。

lambda 表达式

版权声明与致谢
本节基于 Albert Shen 的视频教程《Java中的Lambda - Lambda Expressions in Java》进行整理和撰写。
原教程链接:Java中的Lambda - Lambda Expressions in Java
本文旨在学习与分享,如涉及任何版权问题,请及时与我联系。

lambda 表达式通常被用于实现函数式接口。

函数式接口

什么是接口?

接口(Interface) 被用来定义一系列行为契约,它只声明方法,而不提供方法的具体实现。而这样的方法被称为抽象方法。方法的具体实现由实现这个接口的类来提供,这样一来,将接口的声明与具体实现分开,业务中就只需要关心方法的调用而不需要关心方法的具体实现类,从而实现代码的解耦和模块化。

什么是函数式接口?

有且仅有一个抽象方法的接口被称为 函数式接口(Functional Interface)。函数式接口可以在顶部进行注解 @FunctionalInterface

在面向接口编程中,我们需要创建实现类来实现接口,接着在实现类中实现接口的抽象方法,最后将实现类实例化以调用方法。

而继 Java 8 之后 lambda 表达式的出现帮我们简化了这一步骤。

lambda 表达式

假设我们现在有一个需求:通过一个方法来发送多种不同形式的消息,如 Email、sms 等。

如果是基于传统的面向接口编程,我们需要定义一个接口:

public interface Message {
void send();
}

接着创建实现类来实现接口:

public class Email implements Message {
private String name;

public Email() {
}

@Override
public void send() {
System.out.println("This is an email.");
}
}
public class Sms implements Message {
private String name;

public Sms() {
}

@Override
public void send() {
System.out.println("This is a sms.");
}
}

现在我们就可以实例化并发送消息了:

public class Main {
public static void main(String[] args) {
Message email = new Email();
sendMessage(email);
Message sms = new Sms();
sendMessage(sms);
}

static void sendMessage(Message message) {
message.send();
}
}

但现在我们既然有了 lambda 表达式,我们就可以直接实现接口的抽象方法,而不需要创建类、实例化、调用了:

public class Main {
public static void main(String[] args) {
sendMessage(() -> {
System.out.println("This is an email.");
});
}

static void sendMessage(Message message) {
message.send();
}
}

其中 () -> { System.out.println("This is an email."); } 就等效于用传统方法实现的 Email 实例。

lambda 表达式的基本语法:

(参数列表) -> { 方法体 }
  • 编译器可以推断类型时,可以省略参数类型;
  • 只有一个参数时,可以省略 ()
  • 方法体只有一行时,可以省略 return{}

如:

() -> { System.out.println("Hello Lambda!"); }

x -> { System.out.println(x); }

(a, b) -> a + b

如果一个接口中有多个抽象方法,在使用 lambda 表达式时 Java 将无法确定 lambda 意图实现哪一个抽象方法。所以 lambda 表达式只能用于实现函数式接口