Java1.8新特性:Lambda表达式

函数式接口:

  • 定义:
    • 只包含一个抽象方法的接口,称为函数式接口
    • 可以使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口。同时javadoc会包含说明,这是一个函数式接口
  • 如何理解函数式接口:
    • Java 面向对象。随着其他语言的兴起,为了支持更加广泛的技术要求,java不但支持OOP也可以支持OOF(面向函数编程)
    • lambda表示式是对象,而不是函数,它们必须依附于一类特别的对象类型函数式接口
    • Java中,lambda表达式是一个函数式接口的实例。只要一个对象是函数式接口的实例,那么该对象就可以用lambda表达式来表示

Lambda使用:

  • 格式
    • -> lanmbda操作符或箭头操作符
    • 左边:lambda形参列表(接口中的抽象方法的形参列表)
    • 右边:lambda体(重写方法的方法体)
  • lambda本质是:
    • 作为函数式接口的实例(只有一个抽象方法)
    • 如果一个接口中只声明了一个抽象方法,此接口就称为函数式接口
  • 方法引用:
    • 当传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
    • 方法引用可以看为lambda表达式的深层次表达,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法
  • 要求:
    • 实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
  • 格式:
    • 使用操作符"::"将类(对象)与方法名分割开
    • 对象::实例方法名(非静态)
    • 类::静态方法
    • 类::实例方法名(非静态)

方式一

  1. 无参数,无返回值
public void test1(){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("谎言和誓言的区别是什么");
            }
        };
        runnable.run();

        System.out.println("**************************");

        Runnable runnable1 = () -> System.out.println("听的人信了,说的人信了");
        runnable1.run();
    }
  1. 需要参数,没有返回值
public void test2(){
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("当你凝望深渊时");

        System.out.println("*********************************");

        Consumer<String> consumer1 = (String s) -> System.out.println(s);
        consumer1.accept("深渊也凝望着你");
    }
  1. 数据类型可以省略,因为可由编译器推断得出,成为类型推断
public void test3(){
        Consumer<String> consumer = (s) -> System.out.println(s);
        consumer.accept("在自己的身上克服这个时代");
    }
  1. lambda 如果只需要一个参数,参数的小括号可以省略
public void test4(){
        Consumer<String> consumer = s -> System.out.println(s);
        consumer.accept("每一个不曾起舞的日子,都是对生命的辜负");
    }
  1. lambda 如果需要两个或者两个以上的参数,多条执行语句,并且可以有返回值
public void test5(){
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println(o1);
                System.out.println(o2);
                return o1.compareTo(o2);
            }
        };

        System.out.println("************************");

        Comparator<Integer> comparator1 = (o1,o2) -> {
            System.out.println(o1);
            System.out.println(o2);
            return o1.compareTo(o2);
        };
    }
  1. 当lambda 体只有一条语句时,return 与 大括号若有,都可以省略
public void test6(){
        Comparator<Integer> c1 = (o1, o2) -> o1.compareTo(o2);
        System.out.println(c1.compare(13,12));
    }

方式二

方法引用:
	使用情况:当传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
  1. 对象::实例方法
public void test1(){
        Consumer<String> co1 = str -> System.out.println(str);
        co1.accept("咸鱼");


        System.out.println("**************************");

        Consumer<String> co2 = System.out :: println;
        co2.accept("xianyu");
    }
public void test2(){
        Employee employee = new Employee(999,"小明",18,666);
        Supplier<String> su1 = () -> employee.getName();
        System.out.println(su1.get());


        System.out.println("************************");

        Supplier<String> su2 = employee ::getName;
        System.out.println(su2.get());
    }
  1. 类::静态方法
public void test3(){
        Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2);
        System.out.println(com1.compare(22,21));

        System.out.println("************************");

        Comparator<Integer> com2 = Integer::compare;
        System.out.println(com2.compare(22,21));
    }
public void test4(){
        Function<Double,Long> fun = new Function<Double, Long>() {
            @Override
            public Long apply(Double aDouble) {
                return Math.round(aDouble);
            }
        };
        System.out.println(fun.apply(9.9));

        System.out.println("*******************");

        Function<Double,Long> function = Math::round;
        System.out.println(function.apply(9.9));
    }
  1. 类::非静态方法
public void test5(){
        Comparator<String> com = (c1,c2) -> c1.compareTo(c2);
        System.out.println(com.compare("adc","acd"));

        System.out.println("******************");

        Comparator<String> com1 = String::compareTo;
        System.out.println(com1.compare("abd","adm"));
    }
public void test6(){
        BiPredicate<String,String> biPredicate = (b1,b2) -> b1.equals(b2);
        System.out.println(biPredicate.test("abc","abc"));

        System.out.println("**********************");

        BiPredicate<String,String> bi = biPredicate::test;
        System.out.println(bi.test("abc","abc"));
    }
public void test7(){
        Employee employee = new Employee(888, "小李", 18, 880);
        Function<Employee,String> stringFunction = e -> e.getName();
        System.out.println(stringFunction.apply(employee));

        System.out.println("***********************");

        Function<Employee,String> function = Employee::getName;
        System.out.println(function.apply(employee));
    }
  • 构造器引用
    • 和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。
    • 抽象方法的返回值类型即为构造器所属的类的类型
public void test1(){
        Supplier<Employee> sup = () -> new Employee();
        System.out.println(sup.get());

        System.out.println("*********************");

        Supplier<Employee> sup1 = Employee::new;
        System.out.println(sup1.get());
    }
  • 数组引用
    • 把数组看成一个特殊的类,写法和构造器引用相同
public void test2(){
        Function<Integer,String[]> function = Length -> new String[Length];
        String[] apply = function.apply(6);
        System.out.println(Arrays.toString(apply));

        System.out.println("*********************");

        Function<Integer,String[]> function1 = String[]::new;
        String[] apply1 = function1.apply(6);
        System.out.println(apply1);
    }

猜你喜欢

转载自blog.csdn.net/drsarah/article/details/103606757