一、函数接口

Java 8 引入了 「 函数接口 」 ( funtional interface ) 的概念,「 函数接口 」就是那些有且只有显式定义一个方法的接口,可以被隐式转换为 lambda 表达式。

以下是Java 8 java.util.function 包中定义的函数接口:

接口 说明
BiConsumer<T,U> 表示接受两个不同类型的参数,但不返回任何结果的操作
BiFunction<T,U,R> 表示接受两个不同类型的参数,并返回一个其它类型的结果的操作
BinaryOperator 表示接受两个相同类型的参数,并返回一个同一类型的结果的操作
BiPredicate<T,U> 表示接受两个不同诶行的参数,且返回布尔类型的结果的操作
BooleanSupplier 不接受任何参数,且返回一个布尔类型的结果的操作
Consumer 表示接受一个参数,但不返回任何结果的操作
DoubleBinaryOperator 表示接受两个 double 类型的参数,并返回 double 类型结果的操作
DoubleConsume 表示接受一个 double 类型的参数,但不返回任何结果的操作
DoubleFunction 表示接受一个 double 类型的参数,且返回一个 R 类型的结果的操作
DoublePredicate 表示一个接受两个 double 类型的参数, 且返回一个布尔类型的结果的操作
DoubleSupplier 表示一个不接受任何参数,但返回布尔类型的结果的操作
DoubleToIntFunction 表示接受两个 double 类型的参数,但返回一个 int 类型的结果的操作
DoubleToLongFunction 表示接受两个 double 类型的参数,但返回一个 long 类型的结果的操作
DoubleUnaryOperator 表示接受一个 double 类型的参数,且返回一个 double 类型的结果的操作
Function<T,R> 表示一个接受 T 类型的参数,且返回一个 R 类型结果的函数
IntBinaryOperator 表示一个接受两个 int 类型的参数,且返回一个 int 类型的结果的操作
IntConsumer 表示接受一个 int 类型的参数,但不返回任何结果的操作
IntFunction 表示接受一个 int 类型的参数,但返回一个 R 类型的结果的操作
IntPredicate 表示接受一个 int 类型的参数,但返回布尔类型的结果的操作
IntSupplier 表示不接受任何参数,但返回一个 int 类型的结果的操作
IntToDoubleFunction 表示接受一个 int 类型的参数,但返回一个 double 类型的结果的操作
IntToLongFunction 表示接受一个 int 类型的参数,但返回一个 long 类型的结果的操作
IntUnaryOperator 表示接受一个 int 类型的参数,且返回一个 int 类型的结果的操作
LongBinaryOperator 表示接受两个 long 类型的参数,且返回一个 long 类型的结果的操作
LongConsumer 表示不接受任何参数,但返回一个 long 类型的结果的操作
LongFunction 表示接受一个 loing 类型的参数,但返回一个 R 类型的结果的操作
LongPredicate 表示接受一个 long 类型的参数,但返回布尔类型的结果的操作
LongSupplier 表示不接受任何参数,但返回一个 long 类型的结果的操作
LongToDoubleFunction 表示接受一个 long 类型的参数,但返回一个 double 类型的结果的函数
LongToIntFunction 表示接受一个 long 类型的参数,但返回 int 类型的结果的函数
LongUnaryOperator 表示接受一个 long 类型的参数,并返回一个 long 类型的结果的操作
ObjDoubleConsumer 表示接受两个参数,一个为 T 类型的对象,另一个 double 类型,但不返回任何结果的操作
ObjIntConsumer 表示接受两个参数,一个为 T 类型的对象,另一个 int 类型,但不返回任何结果的操作
ObjLongConsumer 表示接受两个参数,一个为 T 类型的对象,另一个 double 类型,但不返回任何结果的操作
Predicate 表示接受一个指定类型 T 的参数,但返回布尔类型的结果的操作
Supplier 表示不接受任何参数,但返回一个 T 类型的结果的操作
ToDoubleBiFunction<T,U> 表示接受两个不同类型的参数,但返回一个 double 类型的结果的操作
ToDoubleFunction 表示一个接受指定类型 T 的参数,并返回一个 double 类型的结果的操作
ToIntBiFunction<T,U> 表示接受两个不同类型的参数,但返回一个 int 类型的结果的操作
ToIntFunction 表示一个接受指定类型 T 的参数,并返回一个 int 类型的结果的操作
ToLongBiFunction<T,U> 表示接受两个不同类型的参数,但返回一个 long 类型的结果的操作
ToLongFunction 表示一个接受指定类型的参数,并返回一个 long 类型的结果的操作
UnaryOperator 表示接受一个参数,并返回一个与参数类型相同的结果的操作

按类型区分的话主要分为四类Function、Consumer、Supplier以及Predicate。

二、Function

2.1 定义

Function是一个函数,它接受一个参数并产生一个结果。(Represents a function that accepts one argument and produces a result.)

2.2 方法

方法 说明
apply 抽象方法,具体实现业务逻辑
andThen default默认方法,指定一个函数,使用当前函数的输出作为输入
compose default默认方法,指定一个函数,该函数的输出将作为当前函数的输入,与andThen相反
identity static方法,返回自身

2.3 扩展类

  • IntFunction 接受一个int参数,返回指定类型的结果,类似的还有 DoubleFunction LongFunction
  • ToIntFunction 接受一个指定类型参数,返回int类型的结果,类似的还有 ToDoubleFunction ToLongFunction
  • BiFunction 接受两个指定类型参数,产生一个指定类型结果,和Function类似,他也有IntBiFunction、ToIntBiFunction这些方法
  • UnaryOperator Function的子类,区别在于UnaryOperator的参数和返回值类型是相同的,同时拓展了一个identity方法,直接返回参数
  • BinaryOperator BiFunction的子类,BinaryOperator的参数和返回值类型也是相同的,同时拓展了两个方法,minBy以及maxBy,分别返回一个较小值以及一个较大值

2.4 使用

public static void main(String[] args) {
    // 获取字符串长度
    Function<String, Integer> lengthFunction = s -> s.length();
    // 获取数字的平方
    Function<Integer, Double> squareFunction = num -> Math.pow(num.doubleValue(), 2d);

    // identity 返回自身
    System.out.println(Function.identity().apply("hhh"));

    // apply 执行定义的函数
    System.out.println(lengthFunction.apply("hello"));
    System.out.println(squareFunction.apply(100));

    // andThen 可以指定一个函数,使用当前函数的输出作为输入
    System.out.println(lengthFunction.andThen(squareFunction).apply("rabb"));
    // compose 可以指定一个函数,该函数的输出将作为当前函数的输入,与andThen相反
    System.out.println(squareFunction.compose(lengthFunction).apply("apply"));

    // IntFunction 接受一个int参数,返回指定类型的结果,类似的还有 DoubleFunction LongFunction
    IntFunction<String> intFunction = value -> Integer.toString(value);
    // ToIntFunction 接受一个指定类型参数,返回int类型的结果,类似的还有 ToDoubleFunction ToLongFunction
    ToIntFunction<String> toIntFunction = value -> value.length();

    // BiFunction 接受两个指定类型参数,产生一个指定类型结果,和Function类似,他也有IntBiFunction、ToIntBiFunction这些方法
    BiFunction<String, String, Integer> lengthBiFunction = (s1, s2) -> s1.length() + s2.length();

    // UnaryOperator Function的子类,区别在于UnaryOperator的参数和返回值类型是相同的,同时拓展了一个identity方法,直接返回参数
    UnaryOperator<String> unaryOperator = s -> s + "_abc";
    System.out.println(unaryOperator.apply("123"));
    System.out.println(UnaryOperator.identity().apply("123"));

    // BinaryOperator BiFunction的子类,BinaryOperator的参数和返回值类型也是相同的,同时拓展了两个方法,minBy以及maxBy,分别返回一个较小值以及一个较大值
    BinaryOperator<String> binaryOperator = (s1, s2) -> s1 + s2;
    System.out.println(binaryOperator.apply("hello", " world"));
    System.out.println(BinaryOperator.maxBy(Comparator.comparingInt(String::length)).apply("abc", "de"));
}

三、Consumer

3.1 定义

用来消费一个对象,接受一个参数,没有返回值。(Represents an operation that accepts a single input argument and returns no result.)

集合类的foreach方法的参数就是一个Consumer对象。

3.2 方法

方法 说明
accept 抽象方法,具体实现业务逻辑
andThen default默认方法,用来组合另一个消费者,可以对一个参数进行多次消费

3.3 扩展类

  • BiConsumer 传入两个任意类型参数,无返回值
  • DoubleConsumer 传入一个 double 参数,无返回值
  • IntConsumer 传入一个 int 参数,无返回值
  • LongConsumer 传入一个 long 参数,无返回值
  • ObjDoubleConsumer 传入一个任意类型参数,一个 double 参数,无返回值
  • ObjIntConsumer 传入一个任意类型参数,一个 int 参数,无返回值
  • ObjLongConsumer 传入一个任意类型参数,一个 long 参数,无返回值

3.4 使用

public static void main(String[] args) {
    // 用来消费一个对象,接受一个参数,没有返回值,集合类的foreach方法的参数就是一个Consumer对象
    Consumer<String> consumer = System.out::println;
    consumer.accept("123");
    // andThen方法用来组合另一个消费者,可以对一个参数进行多次消费
    consumer.andThen(s -> System.out.println(s.length())).accept("haha");
    // jdk还定义了以下Consumer
    // BiConsumer    传入两个任意类型参数,无返回值
    // DoubleConsumer    传入一个 double 参数,无返回值
    // IntConsumer    传入一个 int 参数,无返回值
    // LongConsumer    传入一个 long 参数,无返回值
    // ObjDoubleConsumer    传入一个任意类型参数,一个 double 参数,无返回值
    // ObjIntConsumer    传入一个任意类型参数,一个 int 参数,无返回值
    // ObjLongConsumer    传入一个任意类型参数,一个 long 参数,无返回值
    BiConsumer<String, Integer> biConsumer = (str, length) -> {
        System.out.println(str.substring(0, length));
    };
    biConsumer.accept("hello world!", 10);
}

四、Supplier

4.1 定义

创建对象的生产者。( Represents a supplier of results.)

它只有一个get方法用来获取对象,扩展了指定类型的Supplier,如BooleanSupplier、DoubleSupplier、IntSupplier以及LongSupplier

4.2 使用

public static void main(String[] args) {
    // 当做创建对象的生产者,提供了一个get方法来获取对象
    Supplier localDateTimeSupplier = LocalDateTime::now;
    System.out.println(localDateTimeSupplier.get());
    Supplier<Integer> randomSupplier = () -> new Random().nextInt(10);
    System.out.println(randomSupplier.get());

    // 默认提供了指定类型的Supplier,如BooleanSupplier、DoubleSupplier、IntSupplier以及LongSupplier
    IntSupplier intSupplier = () -> new Random().nextInt(10);
    System.out.println(intSupplier.getAsInt());
    BooleanSupplier booleanSupplier = () -> new Random().nextInt(10) > 5;
    System.out.println(booleanSupplier.getAsBoolean());
}

五、Predicate

5.1 定义

判断一个参数是否符合条件。(Represents a predicate (boolean-valued function) of one argument.)

5.2 方法

方法 说明
test 抽象方法,具体实现业务逻辑
negate default默认方法,返回一个相反的对象
and default默认方法,返回一个相反的对象
or default默认方法,可以连接多个断言进行或判断
and default默认方法,可以连接多个断言进行且判断

5.3 扩展类

jdk也提供了DoublePredicate、BiPredicate、IntPredicate、LongPredicate

5.4 使用

public static void main(String[] args) {
    // Predicate 断言,Stream 中的 filter() 方法是通过接收一个 Predicate 函数接口实现的
    Predicate<String> predicate = s -> s.contains("a");
    // 可以通过test方法判断其是否符合条件,
    System.out.println(predicate.test("abc"));
    // negate方法返回一个相反的对象
    System.out.println(predicate.negate().test("abc"));
    // 提供了and以及or方法,可以多个断言进行且、或判断
    System.out.println(predicate.and(s -> s.contains("c")).test("ac"));
    System.out.println(predicate.or(s -> s.contains("d")).test("d"));

    // jdk也提供了DoublePredicate、BiPredicate、IntPredicate、LongPredicate
    DoublePredicate doublePredicate = d -> d > 0d;
    System.out.println(doublePredicate.test(-2d));
}