Java8基础知识(四)lambda表达式

lambda表达式

lambda表达式的形式:(parameters) -> expression(parameters) -> {statements;}

其本质是匿名函数,用于延迟执行,即代码不会立即执行且不再执行的情况。

函数式接口

当一个接口仅有一个抽象方法时,称其为函数式接口。当一个对象方法需要这种接口作为参数时,可以使用lambda表达式代替。

最常用的函数式接口有RunnableSupplierConsumerFunctionPredicate等。

函数式接口 参数类型 返回类型 抽象方法名 描述
Runnable run 执行动作
Supplier T get 提供T类型的值
Consumer T accept 处理T类型的值
Function<T, R> T R apply T类型为参数的函数,返回R类型
Predicate T boolean test T类型为参数的布尔值函数

示例代码如下:

package lambda;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class FunctionalInterfaceTest {
    public static void main(String[] args) {
        repeat(10, () -> System.out.println("Repeat!"));

        System.out.println(getName(() -> "Supplier!"));

        showName("Consumer!", (str) -> System.out.println(str));

        System.out.println(getLength("Function!", (str) -> str.length()));

        System.out.println(isPredicate("Predicate!", (str) -> str.equals("Predicate!")));
    }

    public static void repeat(int n, Runnable action) {
        for(int i=0; i<n; i++)
            action.run();
    }

    public static String getName(Supplier<String> supplier) {
        return supplier.get();
    }

    public static void showName(String name, Consumer<String> consumer) {
        consumer.accept(name);
    }

    public static int getLength(String str, Function<String, Integer> function) {
        return function.apply(str);
    }

    public static boolean isPredicate(String str, Predicate<String> predicate) {
        return predicate.test(str);
    }
}

方法引用

某些lambda表达式等价于方法引用。方法引用有三种:

  • object::instanceMethod
  • Class::staticMethod
  • Class::instanceMethod

前两种情况等价于提供方法参数的lambda表达式,对于第三种情况,第一个参数会成为调用该方法的实例。

注:也可以使用thissuper作为引用方法的类。

class Greeter {
    public void greet() {System.out.println("Hello!");}
}

class TimedGreeter extends Greeter {
    public void greet() {
        // 引用父类的方法
        Timer t = new Timer(1000, super::greet);
        t.start;
    }
}

构造器引用

可以引用new方法来构造类的实例。

由于Java限制无法构造泛型数组,可以通过数组构造器引用克服这一限制。

// toArray方法返回Object数组,无法强制类型转换
Object[] people = stream.toArray();
// 利用构造器引用可以使toArray方法提供正确类型的数组
Person[] people = stream.toArray(Person::new);

变量作用域

lambda表达式存在限制:

  1. 表达式的体与嵌套块有相同的作用域。
  2. 表达式捕获的变量(外围作用域中变量)必须是最终变量,即变量初始化之后值不会改变。
  3. 表达式使用的this关键字,指创建这个表达式的方法的this参数。
posted @ 2020-03-27 17:07  Aries99C  阅读(155)  评论(0)    收藏  举报