简介:
Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。
Lambda表达式的语法:
基本语法:
(parameters) -> expression
或
(parameters) ->{ statements; }
下面是Java lambda表达式的简单例子:
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
基本的lambda表达式的例子
现在,我们已经知道什么是lambda表达式,让我们先从一些基本的例子开始。 在本节中,我们将看到lambda表达式如何影响我们编码的方式。 假设有一个玩家List ,程序员可以使用 for 语句 (“for 循环”)来遍历,在Java SE 8中可以转换为另一种形式:
String[] atp = {"Rafael Nadal", "Novak Djokovic",
"Stanislas Wawrinka",
"David Ferrer","Roger Federer",
"Andy Murray","Tomas Berdych",
"Juan Martin Del Potro"};
List<String> players = Arrays.asList(atp);
// 以前的循环方式
for (String player : players) {
System.out.print(player + "; ");
}
// 使用 lambda 表达式以及函数操作(functional operation)
players.forEach((player) -> System.out.print(player + "; "));
// 在 Java 8 中使用双冒号操作符(double colon operator)
players.forEach(System.out::println);
正如您看到的,lambda表达式可以将我们的代码缩减到一行。 同样,在实现Runnable接口时也可以这样使用:
//普通的通过匿名内部类新建线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello,lambda expression!");
}
});
//通过lambda表达式新建线程
new Thread(() -> System.out.println("hello,lambda expression!"));
排序时lambda表达式的用法:
String[] players = {"Rafael Nadal", "Novak Djokovic",
"Stanislas Wawrinka", "David Ferrer",
"Roger Federer", "Andy Murray",
"Tomas Berdych", "Juan Martin Del Potro",
"Richard Gasquet", "John Isner"};
// 1.1 使用匿名内部类根据 name 排序 players
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return (s1.compareTo(s2));
}
});
// 1.2 使用 lambda expression 排序 players
Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
Arrays.sort(players, sortByName);
// 1.3 也可以采用如下形式:
Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));
注意:
使用lambda表达式的前提条件:
1、有且只有一个抽象方法的接口才可以用拉姆达表达式。
2、java的源码中将这样的接口叫做函数式接口,并且用@FunctionalInterface注解进行了标注。比如Runnable接口。
3、我们对自定义接口使用lambda表达式时,如果希望这个接口可有有其他的方法,可以添加default修饰的方法和static修饰的方法。
4、自定义的接口在需要用到lambda表达式时注解可写可不写,写了能够加快编译速度。
@FunctionalInterface
interface Foo1{
//唯一的一个抽象方法
int add(int x, int y);
//default修饰的方法
default int div(int x,int y){
return x/y;
}
//静态方法
static int sub(int x, int y){
return x-y;
}
}