JDK8新特性:Lambda 表达式、方法引用

目录

Lambda 表达式

方法引用

静态方法的引用

实例方法的引用

特定类型的方法引用

构造器引用


 

Lambda 表达式


● Lambda 表达式是 JDK 8开始新增的一种语法形式;

作用:用于简化匿名内部类的代码写法。

格式
(被重写方法的形参列表)->{
被重写方法的方法体代码。}

注意: Lambda 表达式只能简化函数式接口的匿名内部类!!!
什么是函数式接口?
.有且仅有一个抽象方法的接口。
●注意:将来我们见到的大部分函数式接口,上面都可能会有一个@ Functionalinterface 的注解,有该注解的接口就必定是函数式接口。

Test1

package com.xinbao.d6_lambda;

public class LambdaTest1 {
    public static void main(String[] args) {
        Animal a = new Animal() {
            @Override
            public void run() {
                System.out.println("匿名内部类");
            }
        };
        a.run();

        //报错:Lambda表达式不能简化全部匿名内部类,只能简化函数式接口(有且仅有一个抽象方法的接口)的匿名内部类
//        Animal a = () -> {
//            System.out.println("匿名内部类");
//        };

        Swimming s = new Swimming() {
            @Override
            public void swim() {
                System.out.println("swim");
            }
        };
        s.swim();

        Swimming s2 = () -> {
            System.out.println("swimswim");
        };
        s2.swim();
    }
}
abstract class Animal{
    public abstract void run();
}

interface Swimming{
    void swim();
}

Test2

package com.xinbao.d6_lambda;

import com.xinbao.d5_arrays.Student;

import java.util.Arrays;
import java.util.Comparator;
import java.util.function.IntToDoubleFunction;

public class LambdaTest2 {
    public static void main(String[] args) {
        //目标:使用Lambda简化函数式接口
        double[] prices = {11,33,55,66.9};
//        Arrays.setAll(prices, new IntToDoubleFunction() {
//            @Override
//            public double applyAsDouble(int value) {
//                return prices[value] * 0.8;
//            }
//        });

        Arrays.setAll(prices,(int value) -> {
                return prices[value] * 0.8;
            });

        System.out.println(Arrays.toString(prices));
        System.out.println("------------------------");

        Student[] students = new Student[4];
        students[0] = new Student("Bob",182.9,22);
        students[1] = new Student("Tom",186.9,21);
        students[2] = new Student("David",185.9,18);
        students[3] = new Student("Cherry",165.9,20);

//        Arrays.sort(students, new Comparator() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                return Double.compare(o1.getHeight(),o2.getHeight());
//            }
//        });

        Arrays.sort(students, (Student o1, Student o2) -> {
                return Double.compare(o1.getHeight(),o2.getHeight());
            });
        System.out.println(Arrays.toString(students));
    }
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=56607:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\api-app2 com.xinbao.d6_lambda.LambdaTest2
[8.8, 26.400000000000002, 44.0, 53.52000000000001]
------------------------
[Student{name='Cherry', height=165.9, age=20}, Student{name='Bob', height=182.9, age=22}, Student{name='David', height=185.9, age=18}, Student{name='Tom', height=186.9, age=21}]

Process finished with exit code 0

Lambda 表达式的省略写法(进一步简化 Lambda 表达式的写法)
·参数类型可以省略不写。
●如果只有一个参数,参数类型可以省略,同时()也可以省略。
●如果 Lambd 表达式中的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号!此时,如
果这行代码是 return 语句,也必须去掉 return 不写。

package com.xinbao.d6_lambda;

import com.xinbao.d5_arrays.Student;

import java.util.Arrays;
import java.util.Comparator;
import java.util.function.IntToDoubleFunction;

public class LambdaTest2 {
    public static void main(String[] args) {
        //目标:使用Lambda简化函数式接口
        double[] prices = {11,33,55,66.9};
//        Arrays.setAll(prices, new IntToDoubleFunction() {
//            @Override
//            public double applyAsDouble(int value) {
//                return prices[value] * 0.8;
//            }
//        });

//        Arrays.setAll(prices,(int value) -> {
//                return prices[value] * 0.8;
//            });

//        Arrays.setAll(prices,value -> {
//            return prices[value] * 0.8;
//        });

        Arrays.setAll(prices,value -> prices[value] * 0.8);

        System.out.println(Arrays.toString(prices));
        System.out.println("------------------------");

        Student[] students = new Student[4];
        students[0] = new Student("Bob",182.9,22);
        students[1] = new Student("Tom",186.9,21);
        students[2] = new Student("David",185.9,18);
        students[3] = new Student("Cherry",165.9,20);

//        Arrays.sort(students, new Comparator() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                return Double.compare(o1.getHeight(),o2.getHeight());
//            }
//        });

//        Arrays.sort(students, (Student o1, Student o2) -> {
//                return Double.compare(o1.getHeight(),o2.getHeight());
//            });

//        Arrays.sort(students, (o1, o2) -> {
//            return Double.compare(o1.getHeight(),o2.getHeight());
//        });

        Arrays.sort(students, (o1, o2) -> Double.compare(o1.getHeight(),o2.getHeight()));
        System.out.println(Arrays.toString(students));
    }
}
方法引用
静态方法的引用


类名::静态方法。
使用场景
.如果某个 Lambda 表达式里只是调用一个静态方法,并且前后参数的形式一致,就可以使用静态方法引用。

实例方法的引用


对象名::实例方法。
使用场景
●如果某个 Lambda 表达式里只是调用一个实例方法,并且前后参数的形式一致,就可以使用实例方法引用。

package com.xinbao.d6_lambda;

import com.xinbao.d5_arrays.Student;

public class CompareByData {
    public static int compareByAge(Student o1, Student o2){
        return o1.getAge() - o2.getAge();
    }
    
    public int compareByAgeDesc(Student o1,Student o2){
        return o2.getAge() - o1.getAge();//降序
    }
}
package com.xinbao.d6_lambda;

import com.xinbao.d5_arrays.Student;

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

public class Test3 {
    public static void main(String[] args) {
        Student[] students = new Student[4];
        students[0] = new Student("Bob",182.9,22);
        students[1] = new Student("Tom",186.9,21);
        students[2] = new Student("David",185.9,18);
        students[3] = new Student("Cherry",165.9,20);

//        Arrays.sort(students, new Comparator() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                return o1.getAge() - o2.getAge();
//            }
//        });

        //使用Lambda化简后的形式
//        Arrays.sort(students,(o1, o2) -> o1.getAge() - o2.getAge());

        //将return封装到静态方法中
//        Arrays.sort(students,(o1, o2) -> CompareByData.compareByAge(o1, o2));

        //静态方法引用
        Arrays.sort(students,CompareByData::compareByAge);

        CompareByData compare = new CompareByData();
//        Arrays.sort(students,((o1, o2) -> compare.compareByAgeDesc(o1, o2)));
       //实例方法引用
        Arrays.sort(students,(compare::compareByAgeDesc));

    }
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=58601:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\api-app2 com.xinbao.d6_lambda.Test3
[Student{name='David', height=185.9, age=18}, Student{name='Cherry', height=165.9, age=20}, Student{name='Tom', height=186.9, age=21}, Student{name='Bob', height=182.9, age=22}]
[Student{name='Bob', height=182.9, age=22}, Student{name='Tom', height=186.9, age=21}, Student{name='Cherry', height=165.9, age=20}, Student{name='David', height=185.9, age=18}]

Process finished with exit code 0
特定类型的方法引用


类型::方法。
使用场景
●如果某个 Lambda 表达式里只是调用一个实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数都是作为该实例方法的入参的,则此时就可以使用特定类型的方法引用。

package com.xinbao.d6_lambda;

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

public class Test4 {
    public static void main(String[] args) {
        String[] names = {"baby","angela","Andy","dlei","cindy","Babo","jaCk","CIci"};
        Arrays.sort(names);
        System.out.println(Arrays.toString(names));//[Andy, Babo, CIci, angela, baby, cindy, dlei, jaCk]

        //忽略首字母大小进行排序
//        Arrays.sort(names, new Comparator() {
//            @Override
//            public int compare(String o1, String o2) {
//                return o1.compareToIgnoreCase(o2);
//            }
//        });

        //Lambda表达式
       // Arrays.sort(names,(o1,o2) -> o1.compareToIgnoreCase(o2));

        //特定类型的方法引用
        Arrays.sort(names,String::compareToIgnoreCase);

        System.out.println(Arrays.toString(names));//[Andy, angela, Babo, baby, CIci, cindy, dlei, jaCk]
    }
}
构造器引用


类名:: new 。
使用场景
.如果某个 Lambda 表达式里只是在创建对象,并且前后参数情况一致,就可以使用构造器引用。

package com.xinbao.d6_lambda;

public class Car {
    private String name;
    private double price;

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    public Car(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public Car() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
package com.xinbao.d6_lambda;

public class Test5 {
    public static void main(String[] args) {
        //1、创建这个接口的匿名内部类对象
//        CreaterCar car = new CreaterCar() {
//            @Override
//            public Car create(String name, double price) {
//                return new Car("特斯拉",100.5);
//            }
//        };

        //Lambda表达式
        //CreaterCar car = (name, price) -> new Car("特斯拉",100.5);

        //构造器引用
        CreaterCar car = Car::new;
        Car c = car.create("特斯拉",100.5);

        System.out.println(c);//Car{name='特斯拉', price=100.5}
    }
}

interface CreaterCar{
    Car create(String name,double price);//抽象类
}

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