Jdk8中的函数式编程接口类型

流继承关系, DoubbleStream  IntStream  LongStream是针对于基本类型double  int  long,其他基本类型没有对应的流

1. 谓词接口  接受一个T 返回boolean

有Predicate<T>  IntPredicate  LongPredicate  DoublePredicate

Predicate 除了有谓词的意思,还有断定,断言的意思,它的作用就是声明一个或组合的条件,满足为true,不满足为false

看接口中定义的方法, 接口方法中有一个test接口需要我们实现,其他都是默认方法,包括逻辑与,做逻辑非操作,逻辑或。还有一个非基本类型(仅指int   long  daouble)Predicate没有的方法判断两个对象是否相同

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    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);
    }

    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);
    }
}

Predicate接口

DoublePredicate接口   DoublePredicate   IntPredicate  LongPredicate与Predicate没有继承关系

简单使用,定义一组过滤条件,然后取反,将数组转换成流

IntPredicate p =((IntPredicate) x->x > 10).and(x -> x < 20).or(x -> x == 30).negate();
Arrays.stream(new int[]{40, 30, 19, 5}).filter(p).forEach(System.out::println);

---output---
40
5

2. 单元操作接口  接受一个T类型参数  返回T类型对象

单元操作接口有UnaryOperator  LongUnaryOperator  IntUnaryOperator    DoubleUnaryOperator

先看一下UnaryOperator是怎样的结构

@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {

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

我们看到只有一个静态方法(在Java8中是允许存在实现的静态方法的),没有看到需要实现的接口方法,但是它继承了Function<T, T>这个单元函数接口,看一下这个单元函数接口的类结构如下图:

我们补全从父类继承的接口方法

@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {

    T apply(T t);
    
    //这个函数的功能是先执行 before 这个表达式的操作,再执行apply
    default <V> Function<V, T> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
    
    //这个函数的功能是先执行apply,再执行 before 这个表达式的操作
    default <V> Function<T, V> andThen(Function<? super T, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

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

然后我们在看IntUnaryOperator操作接口

@FunctionalInterface
public interface IntUnaryOperator {

    int applyAsInt(int operand);

    default IntUnaryOperator compose(IntUnaryOperator before) {
        Objects.requireNonNull(before);
        return (int v) -> applyAsInt(before.applyAsInt(v));
    }

    default IntUnaryOperator andThen(IntUnaryOperator after) {
        Objects.requireNonNull(after);
        return (int t) -> after.applyAsInt(applyAsInt(t));
    }

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

发现这个接口并没有和UnaryOperator接口一样继承Function<T,R>单元函数接口,作者认为UnaryOperator是一个特殊的单元函数接口

简单使用一下,先+2  在+1  然后×3

IntUnaryOperator u1 = ((IntUnaryOperator)x -> x+1).compose(x -> x+2).andThen(x -> x*3);
Arrays.stream(new int[]{40, 30, 19, 5}).map(u1).forEach(System.out::println);

--output--
129
99
66
24 

3. 二元操作接口  接受两个T参数  返回T类型对象

有BinaryOperator  LongBinaryOperator  IntBinaryOperator  DoubleOperator

同一元操作接口,二元操作接口继承了二元函数接口

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
    
    //补全
    int apply(int t1, int t2)
    
    //补全  先执行apply 在执行after操作
    default <V> BiFunction<T, T, V> andThen(Function<? super T, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t, T t1) -> after.apply(apply(t, t1));
    }
    
    //找最大值
    public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
    }

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

而IntBinaryOperator只有一个方法

@FunctionalInterface
public interface IntBinaryOperator {

    int applyAsInt(int left, int right);
}

二元操作接口可以用在reduce聚合操作上

Arrays.stream(new int[]{40, 30, 19, 5}).reduce((x, y) -> {    
    System.out.println("(" + x + "," + y + ")");    
    return x + y;
}).ifPresent(System.out::println);​

--output--
(40,30)
(70,19)
(89,5)
94

4. 单元函数 Function<T,R> 接收一个T类型的参数,返回一个R类型对象

@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);

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

    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;
    }
}
这个函数的功能和前面介绍的单元操作接口一样,唯一的区别是单元函数关心函数的返回值,可以将T->R

简单使用一下

IntFunction<String> i = x -> x + "intToStringFunction";
Arrays.stream(new int[]{40, 30, 19, 5}).mapToObj(i).forEach(System.out::println);

Function<Integer, String> its = x -> x + "function";
System.out.println(its.apply(1));

--output--
40intToStringFunction
30intToStringFunction
19intToStringFunction
5intToStringFunction
1function

除了Function, IntFunction, DoubleFunction, LongFunction,还提供了int long double互相转换的Function,例如IntToDoubleFunction,IntToLongFunction等单元函数接口,如果基本类型只明确了接受参数类型则会使用IntFunction, DoubleFunction, LongFunction,如果基本类型接受参数和返回类型都明确则会使用互转的函数接口。

5. 二元函数接口 接受两个参数T,U类型,返回R类型对象

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

    R apply(T t, U u);

    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));
    }
}

简单使用一下

BiFunction<Integer, String, String> b = (x,y)->"(" + x + "," + y + ")";
System.out.println(b.apply(1, "one"));
--output--
(1,one)

除了BiFunction还有ToDoubleBiFunction  ToLongBiFunction  ToIntBiFunction确定返回类型的接口

6.消费者接口,接受T  返回void

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

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

简单使用一下

Arrays.stream(new int[]{40, 30, 19, 5}).forEach(System.out::println);​

除了Consumer<T> 还有IntConsumer  DoubleConsumer  LongConsumer

7. 二元消费者接口,接受T,U 返回void  BiConsumer<T,U>

@FunctionalInterface
public interface BiConsumer<T, U> {
   
    void accept(T t, U u);
   
    default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {
        Objects.requireNonNull(after);

        return (l, r) -> {
            accept(l, r);
            after.accept(l, r);
        };
    }
}

简单使用一下

BiConsumer<Integer, String> bc = (x, y) -> System.out.println("(" + x + "," + y + ")");
bc.accept(1,"2");

8. 工厂接口 

@FunctionalInterface
public interface Supplier<T> {
    T get();
}
简单使用一下
Arrays.stream(new int[]{40, 30, 19, 5}).filter(x->x>20).collect(ArrayList::new, ArrayList::add, ArrayList::addAll).forEach(System.out::println);

除了Supplier<T>  还有IntSupplier  BooleanSupplier  DoubleSupplier LongSupplier

猜你喜欢

转载自blog.csdn.net/qq_19457117/article/details/81134860
今日推荐