一、Lambda表达式
1.Lambda的语法规则
Lambda省去了面向对象的条条框框,Lambda的标准格式由3个部分组成:
(参数类型 参数名称) -> {
代码体;
}
格式说明:
-
(参数类型 参数名称):参数列表
-
{代码体;} :方法体
-
-> :箭头,分割参数列表和方法体
1.1 无参无返回值的Lambda
先定义一个接口:
public interface OrderService {
//下单接口
void addOrder();
}
然后创建主方法使用
public static void main(String[] args){
//第一种方式:匿名内部类
addOrderTest(new OrderService() {
@Override
public void addOrder() {
System.out.println("匿名内部类:新增一个订单");
}
});
//第二种方式:Lambda写法
addOrderTest(() -> {
System.out.println("Lambda:新增一个订单");
});
}
public static void addOrderTest(OrderService orderService){
orderService.addOrder();
}
打印结果:
匿名内部类:新增一个订单
Lambda:新增一个订单
1.2 有参且有返回值的案例
需求:创建一个Student对象,然后我们在List集合中保存多个Student对象,然后对这些对象做根据age排序操作
@Data
public class Student {
private Long id;
private String name;
private Integer age;
}
开始写代码完成需求:
public static void main(String[] args){
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1L, "张三", 20));
studentList.add(new Student(2L, "李四", 22));
studentList.add(new Student(3L, "王五", 28));
studentList.add(new Student(4L, "赵六", 25));
//排序:升序
Collections.sort(studentList, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
//打印List集合值
for(int i=0; i<studentList.size(); i++){
System.out.println(studentList.get(i));
}
}
//第二种方式:Lambda写法
public static void main(String[] args){
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1L, "张三", 20));
studentList.add(new Student(2L, "李四", 22));
studentList.add(new Student(3L, "王五", 28));
studentList.add(new Student(4L, "赵六", 25));
//排序:升序
Collections.sort(studentList,(Student s1, Student s2)-> {
return o1.getAge() - o2.getAge();
});
//打印List集合值
for(int i=0; i<studentList.size(); i++){
System.out.println(studentList.get(i));
}
}
打印结果:
Student(id=1, name=张三, age=20)
Student(id=2, name=李四, age=22)
Student(id=4, name=赵六, age=25)
Student(id=3, name=王五, age=28)
2.Lambda表达式的省略写法
在lambda表达式的标准写法基础上,可以使用省略写法
规则:
1.如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写,同时要省略分号
Thread t2 = new Thread(() -> {
System.out.println(Thread.currentThread().getName()+"执行");
});
//简写方式:
Thread t3 = new Thread(() ->
System.out.println(Thread.currentThread().getName()+"执行")
);
2.如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写 同时要省略分号 return也可以省略
Collections.sort(ls,(Student o3, Student o4) ->{
return o3.getAge()-o4.getAge();
});
//简写方式:
Collections.sort(ls,(Student o3, Student o4) ->o3.getAge()-o4.getAge());
3.参数类型可以省略不写
Collections.sort(ls,(Student o3, Student o4) ->{
return o3.getAge()-o4.getAge();
});
//简写方式:
Collections.sort(ls,( o3, o4) ->o3.getAge()-o4.getAge());
4.如果只有一行代码 并且只有一个参数 参数类型和括号都可以省略 可以直接省略花括号 return也可以省略
// 匿名函数的完整写法
Thread t = new Thread((Runnable r) -> {
return r.run();
});
// 如果只有一行代码 参数类型和括号都可以省略 可以直接省略花括号 return可以省略
Thread t = new Thread(r -> r.run());
3.Lambda表达式的使用前提
Lambda表达式的语法是非常简洁的,但是Lambda表达式不是随便使用的,使用时有几个条件需要注意:
-
方法的参数或局部变量类型必须为接口才能使用Lambda
-
接口中有且仅有一个抽象方法(@FunctionalInterface)
4.Lambda和匿名内部类的对比
Lambda和匿名内部类的对比
1.所需类型不一样
-
匿名内部类的类型可以是 类,抽象类,接口
-
Lambda表达式需要的类型必须是接口
2.抽象方法的数量不一样
-
匿名内部类所需的接口中的抽象方法的数量是随意的
-
Lambda表达式所需的接口中只能有一个抽象方法
3.实现原理不一样
-
匿名内部类是在编译后形成一个class
-
Lambda表达式是在程序运行的时候动态生成class