Java 函数式编程 - 函数式接口


Java 函数式编程 - 函数式接口

概念

函数式接口在 Java 中是指:有且仅有一个抽象方法的接口

函数式接口可以被隐式转换为 Lambda 表达式

@FunctionalInterface

@FunctionalInterface // 标明为函数式接口
public interface MyFunctionInterface {
    void mrthod(); //抽象方法
}

一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。(该接口是一个标记接口)

常用的函数式接口

Supplier 接口

@FunctionalInterface
public interface Supplier {
    T get();
}

用来返回一个值,即供应器

Consumer 接口

@FunctionalInterface
public interface Consumer {

    void accept(T t);

    default Consumer andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

用来消费一个值,即消费器

默认方法

  • andThen:组合多个 consumer,可以实现消费数据的时候,首先做一个操作,然后再做一个操作
Consumer consumer = ((Consumer) i -> System.out.println("a" + i))
    .andThen(i -> System.out.println("b" + i));

Stream.of(1, 2, 3, 4).forEach(consumer);
// 输出:a1 b1 a2 b2 a3 b3 a4 b4

Predicate 接口

@FunctionalInterface
public interface Predicate {

    boolean test(T t);

    default Predicate negate() {
        return (t) -> !test(t);
    }

    default Predicate and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    static  Predicate isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

用来判断一个值是否符合条件,即判断器

默认方法

  • negate:取反
  • and:类似于 &&
  • or:类似于 ||

静态方法

  • isEqual:返回一个输入值是否等于目标值的 Predicate 接口

Function 接口

@FunctionalInterface
public interface Function {

    R apply(T t);

    default  Function andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
    
    default  Function compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    static  Function identity() {
        return t -> t;
    }
}

用来将一个值转换成其它类型的值,即转换器

默认方法

  • andThen:组合多个 function,可以实现先做一个转换,再做一个转换
Function mapper = ((Function) i -> i * 10)
    .andThen(i -> i - 1);

Stream.of(1, 2, 3, 4)
    .map(mapper)
    .forEach(System.out::println);
// 输出:9 19 29 39
  • compose:也是组合多个 function,不过组合顺序跟 andThen 相反
Function mapper = ((Function) i -> i * 10)
    .compose(i -> i - 1);

Stream.of(1, 2, 3, 4)
    .map(mapper)
    .forEach(System.out::println);
// 输出:0 10 20 30

静态方法

identity:不做转换,原样返回输入值

UnaryOperator 接口

@FunctionalInterface
public interface UnaryOperator extends Function {

    static  UnaryOperator identity() {
        return t -> t;
    }
}

[[#Function 接口]]的特例,转换前和转换后的类型不变

BiFunction 接口

@FunctionalInterface
public interface BiFunction {

    R apply(T t, U u);

    default  BiFunction andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t, U u) -> after.apply(apply(t, u));
    }
}

[[#Function 接口]]的另一个版本,接收两个值并返回一个新值

BinaryOperator 接口

@FunctionalInterface
public interface BinaryOperator extends BiFunction {

    public static  BinaryOperator minBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
    }

    public static  BinaryOperator maxBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }
}

[[#BiFunction 接口]]的特例,转换前和转换后的类型不变

Java8 新增的函数式接口

Supplier

接口 描述
Supplier 无参数,返回一个结果
BooleanSupplier 代表了 boolean 值结果的提供方
IntSupplier 无参数,返回一个 int 类型结果
LongSupplier 无参数,返回一个结果 long 类型的值
DoubleSupplier 代表一个 double 值结构的提供方

Consumer

接口 描述
Consumer 代表了接受一个输入参数并且无返回的操作
IntConsumer 接受一个 int 类型的输入参数,无返回值
LongConsumer 接受一个 long 类型的输入参数,无返回值
DoubleConsumer 代表一个接受 double 值参数的操作,并且不返回结果
ObjIntConsumer 接受一个 object 类型和一个 int 类型的输入参数,无返回值
BiConsumer 代表了一个接受两个输入参数的操作,并且不返回任何结果
ObjLongConsumer 接受一个 object 类型和一个 long 类型的输入参数,无返回值
ObjDoubleConsumer 接受一个 object 类型和一个 double 类型的输入参数,无返回值

Predicate

接口 描述
Predicate 接受一个输入参数,返回一个布尔值结果
IntPredicate 接受一个 int 输入参数,返回一个布尔值的结果
LongPredicate 接受一个 long 输入参数,返回一个布尔值类型结果
DoublePredicate 代表一个拥有 double 值参数的 boolean 值方法
BiPredicate 代表了一个两个参数的 boolean 值方法

Function

接口 描述
Function 接受一个输入参数,返回一个结果
IntFunction 接受一个 int 类型输入参数,返回一个结果
IntToLongFunction 接受一个 int 类型输入,返回一个 long 类型结果
IntToDoubleFunction 接受一个 int 类型输入,返回一个 double 类型结果
LongFunction 接受一个 long 类型输入参数,返回一个结果
LongToIntFunction 接受一个 long 类型输入,返回一个 int 类型结果
LongToDoubleFunction 接受一个 long 类型输入,返回一个 double 类型结果
DoubleFunction 代表接受一个 double 值参数的方法,并且返回结果
DoubleToIntFunction 接受一个 double 类型输入,返回一个 int 类型结果
DoubleToLongFunction 接受一个 double 类型输入,返回一个 long 类型结果
ToIntFunction 接受一个输入参数,返回一个 int 类型结果
ToLongFunction 接受一个输入参数,返回一个 long 类型结果
ToDoubleFunction 接受一个输入参数,返回一个 double 类型结果

UnaryOperator

接口 描述
UnaryOperator 接受一个参数为类型 T,返回值类型也为 T
IntUnaryOperator 接受一个参数同为类型 int,返回值类型也为 int
LongUnaryOperator 接受一个参数同为类型 long,返回值类型也为 long
DoubleUnaryOperator 接受一个参数同为类型 double,返回值类型也为 double

BiFunction

接口 描述
BiFunction 代表了一个接受两个输入参数的方法,并且返回一个结果
ToIntBiFunction 接受两个输入参数,返回一个 int 类型结果
ToLongBiFunction 接受两个输入参数,返回一个 long 类型结果
ToDoubleBiFunction 接受两个输入参数,返回一个 double 类型结果

BinaryOperator

接口 描述
BinaryOperator 代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果
IntBinaryOperator 接受两个参数同为类型 int,返回值类型也为 int
LongBinaryOperator 接受两个参数同为类型 long,返回值类型也为 long
DoubleBinaryOperator 代表了作用于两个 double 值操作符的操作,并且返回了一个 double 值的结果

参考

  • Java 8 函数式接口 | 菜鸟教程 (runoob.com)