JDK8 Lambda表达式介绍
- 了解Open jdk 和 Oracle jdk
- JDK8 新特性
- Lambda 新特性
- 集合之Stream流式操作
- 接口的增强
- 并行数组排序
- Optional中避免Null检查
- 新的时间和日期API
- 可重复注解
- Open JDK 官网介绍OpenJdk官网
使用匿名内部类存在的问题
当需要启动一个线程去完成任务时,通常会通过Runable接口来定义任务内容,或使用Thread类类启动该线程.
传统写法如下
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("新线程执行代码啦");
}
}).start();
}
由于面向对象的语法要求,首选创建一个Runable接口的匿名类对象来指定线程要执行的任务内容,再将其交给一个线程来启动.
代码分析
对于Runable的匿名内部类用法,可以分析出几点内容:
- Thread类需要Runable接口作为参数,其中的抽象run()是用来指定线程任务内容的核心
- 为了指定run()的方法体,不得不需要Runable接口的实现类
- 为了省去定义一个Runable实现类的麻烦,不得不使用匿名内部类
- 必须覆盖重写抽象run方法,所以方法名称、方法参数、方法返回值不得不在写一遍,且不能写错
- 实际上,似乎只有方法体是关键所在
lambda体验
lambda是一个匿名函数,可以理解为一段可以传递的代码
lambda表达式写法,代码如下
借助java8的全新语法,上述Runable接口的匿名内部类写法可以通过更简单的lambda表达式达到相同的效果
public static void main(String[] args) {
new Thread(()->{
System.out.println("新线程执行代码啦");
}).start();
}
这段代码和刚才执行效果是完全一样的,可以在jdk8或更高的编译级别下通过.从代码的语义中可以看出,我们启动了一个线程,而线程任务的内容以一种更加简洁的形式被指定. 我们只需要将要执行的代码放大到一个lambda表达式中,不需要定义类,不需要创建对象.
我们可以理解 Lambda相当于对接口抽象方法的重写
lambda的优点
简化匿名内部类的使用,语法更加简洁
Lambda省去面向对象的条条框框,Lambda表达式标准格式由3个部分组成:
(参数类型 参数名) -> {
代码体
}
格式说明
- (参数类型 参数名): 参数列表
- {代码体}: 方法体
- ->: 箭头,分割参数和方法体的
Lambda与方法的对比
匿名内部类
public void run() {
System.out.println("新线程执行代码啦");
}
Lambda表达式
() ->{ System.out.println("Lambda执行代码啦"); }
无参数无返回值的Lambda
掌握了Lambda的语法,我们来通过一个案例熟悉Lambda的使用
public interface Swimmable {
public abstract void swimming();
}
public class demo01LambdaUse {
public static void main(String[] args) {
goSwimming(new Swimmable() {
@Override
public void swimming() {
System.out.println("我是匿名内部类的游泳");
}
});
goSwimming( (()->{
System.out.println("我是lambda的游泳");
}));
}
//参数无返回值的Lambda表达式
private static void goSwimming(Swimmable swimmable) {
swimmable.swimming();
}
}
有参数有返回值的Lambda
下面举例演示java.util.Comparator<T>接口的使用场景代码,其中抽象方法定义为:
public abstract int compare(T o1, T o2)当需要对一个对象集合进行排序时, Collections.sort()需要一个Comparator接口实例来指定排序的规则
传统写法
public class Person {
private String name;
private int age;
private double height;
... 省略部分代码
}
package com.example.jdk.demo01Lamdba;
import java.util.*;
/**
* @author meteor
*/
public class demo01LambdaParam {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("刘德华", 55, 178.7));
personList.add(new Person("张学友", 56, 179.7));
personList.add(new Person("郭富城", 57, 177.7));
personList.add(new Person("黎明", 58, 176.7));
Collections.sort(personList, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
});
for (Person person : personList) {
System.out.println(person);
}
}
}
Lambda 写法
package com.example.jdk.demo01Lamdba;
import java.util.*;
/**
* @author meteor
*/
public class demo01LambdaParam {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("刘德华", 55, 178.7));
personList.add(new Person("张学友", 56, 179.7));
personList.add(new Person("郭富城", 57, 177.7));
personList.add(new Person("黎明", 58, 176.7));
Collections.sort(personList,(Person o1, Person o2)->{
return o2.getAge() - o1.getAge();
});
for (Person person : personList) {
System.out.println(person);
}
}
}