Java的Lambda表达式

我们先看以下线程的代码:

public class Test {

    public static void main(String[] args) {

        // 匿名内部类
        Runnable task = new Runnable() {
            @Override
            public void run() { // 覆盖重写抽象方法
                System.out.println("多线程任务执行!");
            }
        };
        new Thread(task).start(); // 启动线程

    }
}

使用Lambda表达式后的代码:

public class Test {

    public static void main(String[] args) {

        //Lambda表达式
        new Thread(() -> System.out.println("多线程任务执行!")).start(); // 启动线程

    }
}

两者执行的结果一样,可见Lambda表达式简化了非常多的代码。

我们在使用匿名内部类时,省去了类的定义,但是仍然存在代码冗余。

而Lambda表达式则进一步省略了匿名内部类的相关代码。

Lambda标准格式。

  • 一些参数
  • 一个箭头
  • 一段代码

Lambda表达式的标准格式为:

(参数类型 参数名称) ‐> { 代码语句 }

格式说明:

  • 小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔
  • -> 是新引入的语法格式,代表指向动作。
  • 大括号内的语法与传统方法体要求基本一致。

练习:(无参)

定义一个接口Fly:

public interface Fly {
    
    public void fly(); 
    
}

测试类:

public class Test {

    public static void main(String[] args) {

        //未使用Lambda
        canFly(new Fly() {
            @Override
            public void fly() {
                System.out.println("我飞了");
            }
        });

        //使用Lambda
        canFly(() -> System.out.println("我飞了"));

    }

    public static void canFly(Fly flyy){
        flyy.fly();
    }

}

Lambda的有参数和返回值:

题目需求:

  • 使用数组存储多个Person对象,对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序

定义Person类:

public class Person {
    
    private String name;
    private int age;
    public Person(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;
    }
}

传统写法:

import java.util.Arrays;
import java.util.Comparator;

public class Test {

    public static void main(String[] args) {

        // 本来年龄乱序的对象数组
        Person[] array = {
                new Person("古力娜扎", 19),
                new Person("迪丽热巴", 18),
                new Person("马尔扎哈", 20) };
                // 匿名内部类
        Comparator comp = new Comparator() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge() - o2.getAge();
            }
        };
        Arrays.sort(array, comp); // 第二个参数为排序规则,即Comparator接口实例
        for (Person person : array) {
            System.out.println(person);
        }

    }

}

代码分析:

  • 为了排序, Arrays.sort 方法需要排序规则,即 Comparator 接口的实例,抽象方法 compare 是关键;
  • 为了指定 compare 的方法体,不得不需要 Comparator 接口的实现类;
  • 为了省去定义一个 ComparatorImpl 实现类的麻烦,不得不使用匿名内部类;
  • 必须覆盖重写抽象 compare 方法,所以方法名称、方法参数、方法返回值不得不再写一遍,且不能写错;
  • 实际上,只有参数和方法体才是关键。

因此,使用Lambda表达式需要传入两个参数,分别为Person o1, Person o2;返回值则是o1.getAge() ‐ o1.getAge();

Lambda表达式为:

import java.util.Arrays;
import java.util.Comparator;

public class Test {

    public static void main(String[] args) {


        // 本来年龄乱序的对象数组
        Person[] array = {
                new Person("古力娜扎", 19),
                new Person("迪丽热巴", 18),
                new Person("马尔扎哈", 20) };
      
        //Lambda表达式
        Arrays.sort(array,(Person o1, Person o2) -> {
            return o1.getAge() - o2.getAge();
        });

        for (Person person : array) {
            System.out.println(person);
        }

    }

}

Lambda的使用前提:

  1. 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。 无论是JDK内置的 Runnable 、 Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一 时,才可以使用Lambda。
  2. 使用Lambda必须具有上下文推断。 也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。

备注:有且仅有一个抽象方法的接口,称为“函数式接口

你可能感兴趣的:(java,开发语言,后端)