你有没有想过,每次处理只有一个抽象方法的接口时,都要写一大段匿名内部类代码?比如启动一个线程,或者对集合排序,这些地方都需要实现一个只有一个方法的接口,代码看起来总是显得有些繁琐。Java 8引入的Lambda表达式,就是为了解决这种“代码冗余”的问题,让我们能用更简洁的方式实现这些简单的函数式接口。
为什么需要Lambda表达式?¶
在Java 8之前,如果要使用只有一个抽象方法的接口(比如Runnable或Comparator),通常需要写一个匿名内部类。例如,启动一个线程时,代码可能像这样:
// 旧写法:使用匿名内部类实现Runnable
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程运行了!");
}
}).start();
这段代码中,new Runnable() {}是匿名内部类,包含了run()方法的实现。但对只有一行逻辑的情况来说,这种写法显得冗余:需要写new Runnable()、@Override和大括号,反而影响了代码的简洁性。
Lambda表达式的出现,就是为了用更简短的语法替代这种繁琐的匿名内部类写法。
什么是函数式接口?¶
要理解Lambda表达式,首先要明白函数式接口的概念:函数式接口是只有一个抽象方法的接口。比如:
- Runnable接口:只有一个run()方法(无参数、无返回值)。
- Comparator接口:只有一个compare(T o1, T o2)方法(两个参数,返回int)。
Java 8还提供了很多内置函数式接口(如Consumer、Supplier等),但对初学者来说,先掌握Runnable和Comparator这类基础接口就够了。
Lambda表达式的语法基础¶
Lambda表达式的核心语法是“参数列表 -> 表达式体”,具体可分为以下几种情况:
1. 无参数的情况¶
如果函数式接口的抽象方法没有参数,参数列表用空括号()表示,表达式体直接写结果。例如:
() -> System.out.println("Hello, Lambda!")
2. 1个参数的情况¶
如果只有一个参数,小括号可以省略,直接写参数名。例如:
s -> System.out.println(s) // 等价于 (String s) -> System.out.println(s)
3. 多个参数的情况¶
参数列表用小括号包裹,类型可省略(编译器自动推断)。例如:
(a, b) -> a + b // 等价于 (int a, int b) -> a + b
4. 表达式体的写法¶
- 单行表达式:如果表达式体只有一行代码,大括号
{}可以省略,结果会自动返回。例如:(a, b) -> a - b。 - 多行表达式:如果有多行代码,必须用大括号,且需要显式写
return。例如:
(a, b) -> {
int result = a * 2 + b;
return result;
}
实例演示:用Lambda简化常见场景¶
场景1:使用Runnable接口(线程)¶
旧写法(匿名内部类):
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程启动了!");
}
}).start();
Lambda简化后:
new Thread(() -> System.out.println("线程启动了!")).start();
解释:()表示无参数,->后直接写run()的逻辑,一行代码搞定。
场景2:使用Comparator接口(排序)¶
对字符串列表按长度排序,旧写法:
List<String> list = Arrays.asList("apple", "banana", "cherry");
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.length() - b.length();
}
});
Lambda简化后:
Collections.sort(list, (a, b) -> a.length() - b.length());
解释:(a, b)是compare的两个参数,->后直接返回长度差,无需大括号和return。
场景3:自定义函数式接口¶
假设我们自定义一个简单的函数式接口Calculator,只有一个add方法:
@FunctionalInterface // 确保是函数式接口(仅一个抽象方法)
interface Calculator {
int add(int a, int b);
}
用Lambda实现它:
Calculator calc = (a, b) -> a + b;
System.out.println(calc.add(3, 5)); // 输出 8
解释:(a, b)对应add的参数,a + b是返回值,一行代码完成接口实现。
总结:Lambda表达式的优势¶
Lambda表达式让代码更简洁、可读性更高,尤其适合处理只有一个抽象方法的函数式接口。通过参数列表 -> 表达式体的语法,我们能用一行代码替代冗长的匿名内部类,大幅减少模板代码,让逻辑更清晰。
掌握Lambda表达式后,你会发现处理线程、集合排序等场景变得异常简单。后续学习中,还可以结合Java 8的Stream API等特性,进一步提升代码效率!