疑问一:如何使用lambda表达式
创建一个Student类,不实现Comparable接口。
public class Student {
private String name;
private Integer age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
Student(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student[" + name + "," + age + "]";
}
}
然后调用Collections.sort(List<T> list, Comparator<? super T> c)
@Test
public void test2() {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("A", 16));
studentList.add(new Student("S", 12));
studentList.add(new Student("D", 21));
studentList.add(new Student("F", 20));
Collections.sort(studentList, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println(studentList);
}
那么此处便可以使用lambda表达式来简化写法:
Collections.sort(studentList, (o1, o2) -> o1.getAge() - o2.getAge());
疑问二:如果接口中存在多个方法,如何判断lambda替换了哪个方法呢?
实际上,能够被lambda替换的接口,必须是函数式接口(只能存在一个抽象方法)。
随便写一个接口试一下:
public interface MyInterface {
void print();
}
public class HongShu {
@Test
public void test1() {
lambdaTest(()->{System.out.println("this is MyInterface");});
}
public void lambdaTest(MyInterface myInterface) {
myInterface.print();
}
}
正常输出:
this is MyInterface
如果在MyInterface中再加一个方法,test1()就会提示错误了:
public interface MyInterface {
void print();
void print1();
}
如果接口变动,实现类就会出现问题,所以需要在接口上加上注解@FunctionalInterface,就会在源头帮我们规定好该接口为函数式接口,如果存在多个抽象方法,就会报错。
@FunctionalInterface
public interface MyInterface {
void print();
}
疑问三: 为什么接口Comparator中compare(),equals()方法同时存在,但是仍然可以作为函数式接口呢?
在@FunctionalInterface的注释中写道:
/*
* If an interface declares an abstract method overriding one of the
* public methods of {@code java.lang.Object}, that also does
* <em>not</em> count toward the interface's abstract method count
* since any implementation of the interface will have an
* implementation from {@code java.lang.Object} or elsewhere.
*/
如果接口声明一个抽象方法重写{java.Lang.Object}的公共方法,也不计入接口的抽象方法计数中,因为接口的任何实现都将从{java.Lang.Object}或其他地方实现。