FP in java8

作者:lanran 发布于:2025年8月15日

java函数式,带着脚镣跳舞

目录 8 节
  1. Java8
  2. Function<T,R>
  3. Supplier
  4. Consumer
  5. Predicate
  6. Other Functional Interface
  7. Comparator
  8. Runnable

Java8

Java没有对函数变量的原生支持,为了吸收FP范式并且保持向下兼容,在Java8中引入了函数式接口的概念(Functional Interface,指那些有且只有一个抽象方法的的接口,但还可以有其他的默认方法),通过将函数包裹在接口的实现类中(作为接口抽象方法的实现)进行传递。在Java8之前这种效果是通过匿名类的方法来实现的,Java8引入的lambda表达式极大地简化了函数式接口的书写,可以直接将一个lambda表达式赋值给类型匹配的函数式接口,将直接内联实现其内部的唯一的抽象方法。

Function<Integer, Function<Integer, Function<Integer, Integer>>> f =
                x -> y -> z -> x + y + z;
Integer added = f.apply(1).apply(2).apply(3);
System.out.println(added);

但是如果函数是递归的,则不能直接使用lambda表达式赋值,因为Java的lambda表达式不支持自引用,只能通过匿名类的方式来实现

Function<BigInteger, BigInteger> factorial = new Function<>() {
    @Override
    public BigInteger apply(BigInteger n) {
        if (n.equals(BigInteger.ONE)) {
             return BigInteger.ONE;
        }
        return n.multiply(apply(n.subtract(BigInteger.ONE)));
    }
};
factorial.apply(BigInteger.valueOf(5));

接下来让我们看看Java官方提供的函数式接口

Function<T,R>

@FunctionalInterface
public interface Function<T, R> {
    
    R apply(T t);

    //NPE if before is null
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    //NPE if after is null
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

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

Function接口是一种映射,apply()函数签名是T->R,接受一个泛型T的参数,返回一个R类型的参数

通过default方法compose()和andThen()可以实现Function的组合

static方法identity()是一个返回自身的映射,单位映射子

对于Function<T,T>还有一个新的接口UnaryOperator

@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
    static <T> UnaryOperator<T> identity() {
        return t -> t;
    }
}

对于两个参数的版本有接口BiFunction<T,U,R****> (T,U)->R

@FunctionalInterface
public interface BiFunction<T, U, R> {

    R apply(T t, U u);

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

同样的对于(T,U)->R 也有一个特化版的函数式接口BinaryOperator,还提供了两个特殊的default函数来获取两个元素的较大值/较小值,在reduce里常用

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {

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

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

Java开发人员并没有定义三个参数的函数式接口,但我们可以自己定义,注意deafult方法完全可以省略

或者使用**柯里化**来减少参数

import java.util.Objects;
import java.util.function.Function;

@FunctionalInterface
public interface TriFunction<T, U, E, R> {
    R apply(T t, U u, E e);

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

Supplier

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

Supplier是一个生产者函数式接口,get()函数签名是void->T,不接受参数返回T类型的值

通常用它作为数据提供者

Consumer

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

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

Consumer是一个消费者函数式接口,accept()的函数签名是T->void

还有一个default方法then()来和其他的Consumer进行组合

通常用它对数据进行终结操作

还有一个接受两个参数的BiConsumer<T,U> (T,U)->void

Predicate

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

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

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

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

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

    
     //since 11
     //NPE if target is null
    @SuppressWarnings("unchecked")
    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return (Predicate<T>)target.negate();
    }
}

Predicate是一个谓词函数式接口,通过test():T->boolean 对T类型的变量进行断言,返回一个布尔值

default方法and()、or()、negate()能实现谓词Predicate的逻辑与或非组合

还有接受两个参数的谓词函数式接口**BiPredicate<T,U> **(T,U)->boolean

Other Functional Interface

还有一些特化的函数式接口

以下占位符均指代Int/Long/Double三种基本数据类型

Function<T,R>

  • XXXFunction (XXX)->R
  • ToXXXFunction (T)->XXX
  • XXXToYYYFunction (XXX)->YYY
  • XXXUnaryOperator (XXX)->XXX
  • ToXXXBiFunction<T,U> (T,U)->XXX
  • XXXBinaryFunction (XXX,XXX)->XXX

Supplier

  • XXXSupplier+BooleanSupplier void ->XXX/boolean

Consumer

  • XXXConsumer (XXX)->void
  • ObjXXXConsumer (T,XXX)->void

Predicate

  • XXXPredicate (XXX)->boolean

Comparator

用于创建比较器/比较器链来进行排序 ,函数签名是(T,T)->int ,通常使用其静态方法来构造比较器

@FunctionalInterface
public interface Comparator<T> {
    
    int compare(T o1, T o2);

    
    boolean equals(Object obj);

    
    default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }

    //NullPointerException if the argument is null
    default Comparator<T> thenComparing(Comparator<? super T> other) {
        Objects.requireNonNull(other);
        return (Comparator<T> & Serializable) (c1, c2) -> {
            int res = compare(c1, c2);
            return (res != 0) ? res : other.compare(c1, c2);
        };
    }

   
    default <U> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
    {
        return thenComparing(comparing(keyExtractor, keyComparator));
    }

    
    default <U extends Comparable<? super U>> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        return thenComparing(comparing(keyExtractor));
    }

   
    default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
        return thenComparing(comparingInt(keyExtractor));
    }

    
    default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
        return thenComparing(comparingLong(keyExtractor));
    }

    
    default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
        return thenComparing(comparingDouble(keyExtractor));
    }

    
    public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
        return Collections.reverseOrder();
    }

    
    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
        return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
    }

    
    public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
        return new Comparators.NullComparator<>(true, comparator);
    }

    
    public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
        return new Comparators.NullComparator<>(false, comparator);
    }

    //NullPointerException if the argument is null
    public static <T, U> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
    {
        Objects.requireNonNull(keyExtractor);
        Objects.requireNonNull(keyComparator);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
                                              keyExtractor.apply(c2));
    }

    //NullPointerException if the argument is null
    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }

    //NullPointerException if the argument is null
    public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
    }

  
    //NullPointerException if the argument is null
    public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
    }

    //NullPointerException if the argument is null
    public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
    }
}

Runnable

实现线程对象的一种方式

void->void

@FunctionalInterface
public interface Runnable {
    /**
     * Runs this operation.
     */
    void run();
}