jdk1.8新特性之Lambda表达式
话不多说,我们通过例子来了解,下面是一个给学生对象排序的代码:
首先 Student 类:
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
接着来一个测试类:
public class Demo07 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("凤姐", 18));
list.add(new Student("如花", 22));
list.add(new Student("小苍", 19));
// 集合排序
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
for (Student student : list) {
System.out.println(student);
}
}
}
通过上面的代码,我们可以看得出来,我们创建一个线程其实真正需要用到的是 compare方法里面的东西而已,而我们面向对象语言又不得不创建一个匿名内部类出来,可以看的出语法很冗余。
面向对象语法的弊端:
1)定义类
2)定义成员变量,成员方法
3)创建对象
4)使用对象
语法很冗余。
所以我们Java就搞出了一个Lambda表达式,目的就是简化我们的匿名内部类的编写。
下面是通过Lambda表达式创建一个线程的代码:
Collections.sort(list, (Student s1, Student s2) -> { return s2.getAge() - s1.getAge(); });
代码是不是看起来非常简洁.
Lambda表达式的格式:
() -> {
}
(): 表示参数列表
->: 没有实际含义,指向
{}: 方法体
我们上面的代码是不是已经非常简洁了?但是,还不是最简洁的,请看:
Collections.sort(list, (o1, o2) -> o2.getAge() - o1.getAge());
小伙伴是不是已经惊呆了…这也太简洁了吧…是的就是这么简洁。
Lambda表达式省略规则:
- 1.参数类型可以省略: (Student s1, Student s2) 省略后 (s1, s2)(即使参数类型不一样也是可以省略的)
- 2.如果只有一个参数()可以省略: (Student s1) 省略后 s1
- 3.如果方法体只有一句代码可以同时省略{} return ;
那我们岂不是在任何地方都可以使用Lambda表达式了鸭~岂不是美滋滋?
不是的,我们使用Lambda表达式是有前提的:
Lambda表达式的2个前提:
-
1.参数或变量是接口的时候
-
2.接口里面只能有一个抽象方法
举个例子理解的更加清晰:
定义一个 Swimmable 接口:
@FunctionalInterface
public interface Swimmable {
public abstract void swimming();
// public abstract void show();
public default void show1() {
}
public default void show2() {
}
}
测试类:
public class Demo09 {
public static void main(String[] args) {
// test01(() -> {});//不可以
// test02(() -> {});
// test03(() -> {});
test04(() -> {});
Swimmable ss = new Swimmable() {
public void swimming() {
}
};
Swimmable sss = () -> {//当变量是接口的时候
};
}
// Lambda表达式的前提:1.参数或变量是接口的时候
public static void test04(Swimmable a) {}//参数是接口
// public static void test03(Dog a) {}
// public static void test02(int a) {}
// public static void test01(Animal a) {}
}