lambda表达式是一个可传递的代码块,可以在以后执行一次或多次
Java自带的数组排序方法sort需要传递一个泛型数组和继承了该泛型的Comparator实现类
Arrays.sort(T[] a, Comparator super T> c)
要使用它排序数组,需要创建自定义Comparator,重新其中的compare方法
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class MyComparator implements Comparator {
@Override
public int compare(Person o1, Person o2) {
return o1.getName().length() - o2.getName().length();
}
}
调用过程
Person[] people = {new Person("tom"), new Person("john")};
Arrays.sort(people, new MyComparator());
在上述调用过程,不用在意哪个类实现了Comparator
因为在java中不能直接传递代码块,所有代码都必须放在类中的方法体,所以我们真正在意的是这个部分的代码块
(Person o1, Person o2) {
return o1.getName().length() - o2.getName().length();
}
使用Lambda表达式可以让我们跳过类和方法,直接传递代码块,需加上->
Arrays.sort(people, (Person o1, Person o2) -> {
return o1.getName().length() - o2.getName().length();
});
可以更加简洁,Lambda表达式可以自动推断出参数类型和返回类型,当代码只有一行时还可省略{}
Arrays.sort(people, (o1, o2) -> o1.getName().length() - o2.getName().length());
只有一个抽象方法的接口称为函数式接口,当使用该接口的对象时,就可用Lambda表达式替换,即Lambda表达式可以传递到接口,如创建Comparator接口:
Comparator myComparator = (o1, o2) -> o1.getName().length() - o2.getName().length();
Arrays.sort(people, myComparator);
又如BiFunction
BiFunction biFunction=(s1, s2) -> s1.length() - s2.length();
Java有现成的方法可以完成你想要传递到其他代码的某个动作,主要有3种情况:
列如对字符串数组排序
String[] s = {"tom", "john"};
Arrays.sort(s, String::compareToIgnoreCase);
String::compareToIgnoreCase相当于以下两种情况
Arrays.sort(s, new Comparator() {
@Override
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
});
Arrays.sort(s, (o1, o2) -> o1.compareToIgnoreCase(o2));
凡是使用函数式接口的地方即可使用方法引用
interface NormalInterface {
void print(String s);
}
void printTest(NormalInterface normalInterface) {
}
传入System.out::println为打印后换行,传入System.out::print为打印不换行
printTest(System.out::println);
printTest(System.out::print);
printTest(new NormalInterface() {
@Override
public void print(String s) {
System.out.println(s);
}
});
printTest(s1-> System.out.println(s1));
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Person::new会推导出并选择带有String参数的构造器
ArrayList names = new ArrayList<>();
names.add("tom");
names.add("john");
Stream stream = names.stream().map(Person::new);
List people = stream.collect(Collectors.toList());
Java无法构造泛型类型T的数组,使用数组构造器引用可以克服这个问题,stream.toArray()默认返回是一个Object类型数组
Object[] objects = stream.toArray();
通过数组构造器引用可让其返回正确的类型
Person[] people = stream.toArray(Person[]::new);
Lambda表达式中使用的变量必须是不能改变的,即初始化之后就不会再赋新值