Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。
Lambda表达式还增强了集合库。 Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。 总的来说,lambda表达式和 stream 是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。
直观一点,看代码:
public class T1 {
public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
System.out.print("hello ");
System.out.println("world");
}
}).start();
}
}
我想启动一个线程,让它打印输出hello world, Thread接收的是一个Runnable的接口,Runnable接口里面只有一个run方法,为了使用run方法,我必须要实现Runnbale接口,很冗余。看一下使用Lambda的效果。
public class T1 {
public static void main(String[] args) {
//使用lambda表达式来实现
new Thread(() -> {
System.out.print("hello ");
System.out.println("world");
}).start();
}
}
是不是看上去比上面的代码要少一点,之所以可以这样使用,是因为Runnable是一个几口,且它里面只有一个方法,new Thread里面的第一个(),表示这个接口中的方法的参数,及Runnable接口中run方法里面的参数,在这里没有参数,后面的{}相当于写在run()方法里面的代码。能够接收Lambda表达式的参数类型,是一个只包含一个方法的接口。只包含一个方法的接口称之为“函数接口”。在这里Runnable就是一个函数接口。
再看一个里面有参数的例子:
自定义一个类
public class Student {
private String name;
private double score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public Student(String name, double score){
this.name = name;
this.score = score;
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestStudent {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("s1", 80));
list.add(new Student("s2", 100));
list.add(new Student("s3", 70));
list.add(new Student("s4", 90));
//排序不用lambda表达式
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o2.getScore(), o1.getScore());
}
});
printList(list);
}
public static void printList(List<Student> list){
for(Student s : list){
System.out.println(s.getName() + ":" + s.getScore());
}
}
}
我想对自定义的类Student按照分数进行排序,必须要实现Compare接口中的compare方法,这是不使用lambda的效果。
如果使用lambda:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestStudent {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("s1", 80));
list.add(new Student("s2", 100));
list.add(new Student("s3", 70));
list.add(new Student("s4", 90));
//使用lambda表达式
Collections.sort(list, (s1, s2) -> {
return Double.compare(s1.getScore(), s2.getScore());
});
printList(list);
}
public static void printList(List<Student> list){
for(Student s : list){
System.out.println(s.getName() + ":" + s.getScore());
}
}
}
使用了lambda表达式后,后面的(s1, s2)就相当于Compare接口中的compare方法中的参数名称,后面的
{return Double.compare(s1.getScore(), s2.getScore());} 就相当于写在compar()方法中。
记住一点即可,只有当某个接口中只有一个方法时才能使用lambda表达式。
个人感觉,我觉的lambda表达式看上去不直接,如果某个人不了解你写的接口,直接看你的lambda表达式还是一脸懵逼的。我自己平时在写代码时基本上不用这种写法,这次是为了面试,才看了下。