Java之lambda表达式总结
一. 使用方法举例
在Java
程序中,我们经常遇到一大堆单方法接口,即一个接口只定义了一个方法,此时可以以匿名类方式编写。如下是一个排序的例子
import java.util.Arrays;
import java.util.Comparator;
public class Main {
public static void main(String[] args) throws Exception {
String[] array = {"ccc", "aaa", "bbb"};
Arrays.sort(array, new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
System.out.println(Arrays.toString(array));
}
}
- 如果使用
Lambda
的方式来编写,可以简化代码如下
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
String[] array = {"ccc", "aaa", "bbb"};
Arrays.sort(array, (s1, s2) -> s1.compareTo(s2));
System.out.println(Arrays.toString(array));
}
}
- 如果使用方法引用的方式来编写,可以简化代码如下
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
String[] array = {"ccc", "aaa", "bbb"};
Arrays.sort(array, String::compareTo);
System.out.println(Arrays.toString(array));
}
}
二. lambda语法详细解释
- 参数是
(s1, s2)
,参数类型、返回值都可以省略,因为编译器可以自动推断出类型。 -> { ... }
表示方法体,所有代码写在内部即可。- 如果只有一行
return xxx
的代码,可以简写成(s1, s2) -> s1.compareTo(s2)
(s1, s2) -> {
return s1.compareTo(s2);
}
// 不需要参数,返回值为 5
() -> 5
// 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 接受一个 string 对象,并在控制台打印,不返回任何值
(String s) -> System.out.print(s)
三. 普通方法引用替代lambda
如下代码在Arrays.sort()
中直接传入了静态方法cmp
的引用,用Main::cmp
表示。因此,所谓方法引用,是指如果某个方法签名和接口恰好一致,就可以直接传入方法引用。因为Comparator<String>
接口定义的方法是int compare(String, String)
,和静态方法int cmp(String, String)
相比,除了方法名外,方法参数一致,返回类型相同,因此,我们说两者的方法签名一致,可以直接把方法名作为Lambda
表达式传入。所以Arrays.sort(array, Main::cmp);
还可以改为Arrays.sort(array, String::compareTo);
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
String[] array = {"ccc", "aaa", "bbb"};
Arrays.sort(array, Main::cmp);
System.out.println(Arrays.toString(array));
}
static int cmp(String s1, String s2) {
return s1.compareTo(s2);
}
}
四. 构造方法引用替代lambda
除了可以引用静态方法和实例方法,我们还可以引用构造方法。
public class Main {
public static void main(String[] args) {
Person p1 = new Person("name1");
System.out.println(p1);
// 匿名类的方式实现实现接口的创建Person的方法
PersonFactory pf2 = new PersonFactory(){
@Override
public Person createPerson(String name) {
return new Person(name);
}
};
Person p2 = pf2.createPerson("name2");
System.out.println(p2);
// 使用lambda的方式实现一个接口,因为要实现的接口只有一个方法
PersonFactory pf3 = (name) -> new Person(name);
Person p3 = pf3.createPerson("name3");
System.out.println(p3);
// 使用 方法引用 直接引用 Person 的构造方法
PersonFactory pf4 = Person::new;
Person p4 = pf4.createPerson("name4");
System.out.println(p4);
}
}
interface PersonFactory {
Person createPerson(String name);
}
class Person {
String name;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
public Person(String name) {
this.name = name;
}
}