3.2 在哪里以及如何使用Lambda

在函数式接口中使用Lambda表达式。

3.2.1 函数式接口

函数式接口是只定义一个抽象方法的接口,可以包含默认方法、静态方法。

JDK函数式接口

测验3.2:函数式接口

下面哪些接口是函数式接口?

public interface Adder{
  int add(int a, int b);
}

public interface SmartAdder extends Adder{
  int add(double a, double b);
}

public interface Nothing{
}

只有Adder是函数式接口,其他都不是函数式接口,SmartAdder有两个抽象方法,Nothing没有抽象方法。

Lambda表达式可代替匿名类,以内联的形式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例。

public static void process(Runnable r) {
        r.run();
    }


// 匿名类
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("hello, world 1");
    }
};

// Lambda表达式
Runnable r2 = () -> System.out.println("hello, world 2");

// invoke
process(r1);
process(r2);
// Lambda表达式
process(() -> System.out.println("hello, world 3"));

3.2.2 函数描述符

函数描述符是Lambda表达式的签名,与赋值的函数式接口中的抽象方法签名一致。

java.time.function中的函数式接口

泛型函数式接口 函数描述符 基本类型函数式接口
Supplier<T> () -> T BooleanSupplier, IntSupplier, LongSupplier, DoubleSupplier
Consumer<T> T -> void IntConsumer, LongConsumer, DoubleConsumer
Predicate<T> T -> boolean IntPredicate, LongPredicate, DoublePredicate
UnaryOperator<T> T -> T IntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator
Function<T, R> T -> R IntFunction<R>, LongFunction<R>, DoubleFunction<R>
ToIntFunction<T>, ToLongFunction<T>, ToDoubleFunction<T>
IntToLongFunction, IntToDoubleFunction, LongToIntFunction, LongToDoubleFunction, DoubleToIntFunction, DoubleToLongFunction
BiConsumer<T, U> (T, U) -> void ObjIntConsumer<T>, ObLongConsumer<T>, ObjDoubleConsumer<T>
BiPredicate<T, U> (T, U) -> boolean
BinaryOperator<T> (T, T) -> T IntBinaryOperator, LongBinaryOperator, DoubleBinaryOperator
BiFunction<T, U, R> (T, U) -> R ToIntBiFunction<T, U>, ToLongBiFunction<T, U>, ToDoubleBiFunction<T, U>

函数式接口传递Lambda表达式,设计上通过自动映射为抽象方法的实现,避免语言变得更为复杂。(与函数类型相比)

测验3.3:在哪里可以使用Lambda?

以下哪些是使用Lambda表达式的有效方式?

  1.  execute(() -> {});
     public void execute(Runnable r){
       r.run();
     }
    

    √,函数描述符为() -> void

  2.  public Callable<String> fetch() {
       return () -> "Tricky example   ; -)";
     }
    

    √,函数描述符为() -> String

  3.  Predicate<Apple> p=(Apple a)-> a.getWeight();
    

    ×,(Apple a)-> a.getWeight();函数描述符为Apple -> Integer,与Predicate<Apple>的函数描述符Apple -> boolean不相符合

JDK1.8中函数式接口加上标记注解@FunctionalInterface,表示该接口会被设计为函数式接口,如果同时定义多个抽象方法,编译器会提示报错“Multiple non-overriding abstract methods found in interface Xxx”。

另一个常见的标记注解是JDK1.5添加的@Override,用来表示方法被重写了。

posted @ 2023-06-28 17:36  夜是故乡明  阅读(13)  评论(0编辑  收藏  举报