Lambda表达式 | 青训营笔记

160 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第9天

Lambda表达式

public static <T extends Comparable<? super T>> void sort (List<T> list)

Collections包下的sort方法:参数是存储了T类型对象的list列表,T类型实现了Comparable接口,对Comparable的约束是存储所有T的父类。将列表中元素自然升序排序,前提是元素自己需要实现Comparable接口(实现compareTo比较大小的方法)。

public static <T> void sort (List<T> list, Comparator<? super T> c)

T类型对象不需要实现Comparable接口,但需要额外传入一个可以对所有T类型父类进行比较的比较器对象Comparator,所有列表中任意两个元素都可以使用Comparator进行比较。

public interface Comparator<T> {int compare(T o1, T o2); ... }

eg.
// 等价于新建一个class实现Comparator接口
Comparator<Employee> compareById = new Comparator<Employee>() {
    public int compare(Employee o1, Employee o2) {
        return o1.getId().compareTo(o2.getId()); // Integer类本身就实现了compareTo方法
    }
}
Collections.sort(employees, compareById);

当接口里只有一个函数时,可采用函数式接口【只包含一个抽象方法声明的接口,实现对象等价于一个Lambda表达式】:button.addActionListener( (e) -> {System.out.println(e)} );

即减少了一层对于方法的对象封装,参数->函数型构。

由于Java缺少函数式编程的特点,新增了语言级的新特性lambda表达式,不用特别地将函数封装在类中。函数应该做到避免副作用,只能改变内部局部变量的状态,使得并发度尽量高减少加锁。

本质是一个匿名函数。

一般函数有返回值、方法名、参数列表、方法体,而Lambda表达式函数只有参数列表和方法体,形如:

(type1 arg1, type2 arg2) -> {body} 参数列表中的参数类型可以同时省略,编译器可以通过接口函数声明推断,编译时ide会自动补充。只有一个参数时,可以省略小括号;方法体中只有一条语句时,可省略花括号。

public class lambda {
    public static void main(String[] args) {
        List<Cat> catList = new ArrayList<>();
        catList.add(new Cat("a",1));
        catList.add(new Cat("b",5));
        catList.add(new Cat("c",3));
        catList.add(new Cat("d",4));
        catList.add(new Cat("e",2));
        // sort
        System.out.println("lambda sort elements");
        catList.sort((o1, o2) -> {
            return (o1.getAge() - o2.getAge());
        });
        System.out.println(catList);
        // traverse collection
        catList.forEach(System.out::println);
    }