Java 8 function包 部分函数介绍

最近看公司推荐代码,许多的模板类采用函数式编程的方式,借着疑问看了下Java8 function 包相关知识。

接口 解释
Function<T, R> 接收T对象,返回R对象
Consumer<T> 接收T对象,无返回值
Predicate<T> 接收T对象,返回boolean值
Supplier<T> 提供T对象(如工厂),不接受值
BiFunction<T, U, R> 接收T对象&U对象,返回R对象
UnaryOperator<T> 接收T对象,返回T对象,继承于Function
BinaryOperator<T> 接收两个T对象,返回T对象,继承于BiFunction

 

标注为FunctionalInterface的接口被称为函数式接口,该接口只能有一个自定义方法(未实现的方法),所有标注了该注解的接口都将能用在lambda表达式 :

  1. 改注解只能标记在有且仅有一个抽象方法接口上;
  2. JDK8接口中的静态方法(static)和默认方法(default),均不为抽象方法;
  3. Java所有的类均继承Object,接口显示声明覆盖Object中的方法,也不算抽象方法;
  4. 如果接口符合“函数式接口”规范,不加@FunctionalInterface也为函数式接口,有改注解会进行编译器检查。违反函数式接口定义,即使加上该注解,编译器依旧会报错。即@FunctionalInterface非必须

  补充:接口中所有的方法默认为public,所有的参数默认为是static和final的参数

一、Function<T, R>

@FunctionalInterface
public interface Function<T, R> {

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);

    /**
     * Returns a composed function that first applies the {@code before}
     * function to its input, and then applies this function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of input to the {@code before} function, and to the
     *           composed function
     * @param before the function to apply before this function is applied
     * @return a composed function that first applies the {@code before}
     * function and then applies this function
     * @throws NullPointerException if before is null
     *
     * @see #andThen(Function)
     */
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    /**
     * Returns a composed function that first applies this function to
     * its input, and then applies the {@code after} function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of output of the {@code after} function, and of the
     *           composed function
     * @param after the function to apply after this function is applied
     * @return a composed function that first applies this function and then
     * applies the {@code after} function
     * @throws NullPointerException if after is null
     *
     * @see #compose(Function)
     */
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    /**
     * Returns a function that always returns its input argument.
     *
     * @param <T> the type of the input and output objects to the function
     * @return a function that always returns its input argument
     */
    static <T> Function<T, T> identity() {
        return t -> t;
    }

一、Function<T, R>

Function<T, R>属于泛型类,T代表传入的对象,R代表返回的结果对象。大致意思为传入T经过某些逻辑处理,最终返回R 有点类似 y = f(x)的关系该Function(f)就是所定义的从T(x)到R(y)的逻辑处理关系(一元方程组)。所以Function中没有具体的操作,具体的操作需要我们去为它指定,因此apply具体返回的结果取决于传入的lambda表达式

  1、apply方法 -- apply用于执行从T到R所定义的逻辑关系。所以Function中没有具体的操作,具体的操作需要开发人员去指定,因此具体的返回结果取决于传入的lamdba表达式。

  R apply(T t);

  2、compose方法 -- compose接收一个Function参数,返回时先用传入的逻辑执行apply,然后使用当前Function的apply。

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

  例子: 

  public void testCompose(){
      Function<Integer,Integer> A=i->i+1;
      Function<Integer,Integer> B=i->i*i;
      System.out.println(B.compose(A).apply(4)); /* 结果为25 */   
  }

  3、andThen方法 -- andThen跟compose方法执行顺序相反,andThen先执行当前的逻辑,再执行参数传入的逻辑。

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

  例子:

  public void testAndThen(){
      Function<Integer,Integer> A=i->i+1;
      Function<Integer,Integer> B=i->i*i;
      System.out.println(B.andThen(A).apply(4)); /* 结果为17 */   
  }

  4、 identity方法 -- identity方法用于返回输出跟输入一样的lambda表达式对象,一般个人使用比较多的情况是stream流转map过程中key覆盖问题时使用。

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

二、Consumer<T>

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

  1、accept -- accept方法跟Function<T, R>的apply方法差别为无返回值。

  例子:

  AcceptTest acceptTest = new AcceptTest("ID_小汤","博客园");//构造函数参数1为属性name 参数2为属性origin
  Consumer<AcceptTest> consumerFun = o -> o.setName("Tony");
  consumerFun.accept(acceptTest);
  System.out.println(acceptTest.getName()); //输出值为Tony

  2、andThen -- andThen方法跟Function<T, R>的andThen含义相同,为先执行当前定义accept逻辑,然后再执行传入的accept定义逻辑。

  例子:

  AcceptTest acceptTest = new AcceptTest("ID_小汤","博客园");//构造函数参数1为属性name 参数2为属性origin
  Consumer<AcceptTest> consumerFun1 = o -> o.setName("Tony");
  Consumer<AcceptTest> consumerFun2 = o -> o.setName("小汤");
    //先做 consumerFun1 的操作,再做 consumerFun12的操作
  consumerFun1.andThen(consumerFun2).accept(acceptTest);
  System.out.println(acceptTest.getName()); //输出值为 小汤

三、Predicate<T>

@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);

    /**
     * Returns a composed predicate that represents a short-circuiting logical
     * AND of this predicate and another.  When evaluating the composed
     * predicate, if this predicate is {@code false}, then the {@code other}
     * predicate is not evaluated.
     *
     * <p>Any exceptions thrown during evaluation of either predicate are relayed
     * to the caller; if evaluation of this predicate throws an exception, the
     * {@code other} predicate will not be evaluated.
     *
     * @param other a predicate that will be logically-ANDed with this
     *              predicate
     * @return a composed predicate that represents the short-circuiting logical
     * AND of this predicate and the {@code other} predicate
     * @throws NullPointerException if other is null
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    /**
     * Returns a predicate that represents the logical negation of this
     * predicate.
     *
     * @return a predicate that represents the logical negation of this
     * predicate
     */
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    /**
     * Returns a composed predicate that represents a short-circuiting logical
     * OR of this predicate and another.  When evaluating the composed
     * predicate, if this predicate is {@code true}, then the {@code other}
     * predicate is not evaluated.
     *
     * <p>Any exceptions thrown during evaluation of either predicate are relayed
     * to the caller; if evaluation of this predicate throws an exception, the
     * {@code other} predicate will not be evaluated.
     *
     * @param other a predicate that will be logically-ORed with this
     *              predicate
     * @return a composed predicate that represents the short-circuiting logical
     * OR of this predicate and the {@code other} predicate
     * @throws NullPointerException if other is null
     */
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    /**
     * Returns a predicate that tests if two arguments are equal according
     * to {@link Objects#equals(Object, Object)}.
     *
     * @param <T> the type of arguments to the predicate
     * @param targetRef the object reference with which to compare for equality,
     *               which may be {@code null}
     * @return a predicate that tests if two arguments are equal according
     * to {@link Objects#equals(Object, Object)}
     */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

  1、test方法 -- test方法根据自定义的逻辑当参数去返回true/false。

  boolean test(T t);

  例子:

    User user = new User(); //初始化属性age = 20; name = "ID_小汤";company = "苏宁易购"
    Predicate<Test> predicate = o -> o.getAge() < 20;
    System.out.print(predicate.test(user));

  2、and方法 -- 两个逻辑与合并(类似SQL的and逻辑)

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

  例子:

  String otherCompany = "阿里巴巴";
  User user = new User();// name = "ID_小汤" age = "20" company = "苏宁易购"
  Predicate<User> predicate1 = o -> o.getAge() < 20; //逻辑函数1 
  Predicate<User> predicate2 = o -> otherCompany.equals(o.getCompany()); //逻辑函数2 
  System.out.print(predicate1.and(predicate2).test(user)); //逻辑与 结果为false

  3、negate方法 -- 是Predicate的test方法结果取反

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

   例子:

    User user = new User(); // name = "ID_小汤" age = "20" company = "苏宁易购"
    Predicate<User> predicate = o -> o.getAge() < 20; //逻辑函数1
    System.out.print(predicate.negate().test(user));

  4、or方法 -- 用于多逻辑函数或逻辑 (类似SQL的or逻辑)

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

  例子:

    String otherCompany = "阿里巴巴";
    User user = new User(); // name = "ID_小汤" age = "20" company = "苏宁易购"
    Predicate<User> predicate1 = o -> o.getAge() < 20; //逻辑函数1
    Predicate<User> predicate2 = o -> otherCompany.equals(o.getCompany()); //逻辑函数2
    System.out.println(predicate1.or(predicate2).test(user)); //逻辑与 结果为false

  5、isEqual方法 -- 用于根据定义逻辑判断条件是否相同(euqals)

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

  例子:

    User user = new User(); // name = "ID_小汤" age = "20" company = "苏宁易购"
    Predicate<User> predicate =  Predicate.isEqual(user);
    //在集合中找出与user相同的对象 equals 和 hashcode已重写 名字相同变相同
    List<User> sameUserList = userList.stream().filter(predicate).collect(Collectors.toList());

四、Supplier<T>

  @FunctionalInterface
  public interface Supplier<T> {

      /**
       * Gets a result.
       *
       * @return a result
       */
      T get();
  }

  1、get方法 -- 用于返回一个对象(有点像工厂的意思)

  例子:

    /* 常规new方式 开始 */
    User user1 = new User();
    User user2 = new User();
    System.out.println("user1:"+user1.getAge() + "  user2:"+user2.getAge()+"  user1==user2:"+(user1==user2)); //user1:18  user2:18  user1==user2:false
    /* Supplier生成对象 开始 */
    Supplier<User> s = () -> new User();
    user1 = s.get();
    user2 = s.get();
    //System.out.println("user1:"+s.get().getAge() + "  user2:"+s.get().getAge());
    System.out.println("user1:"+user1.getAge() + "  user2:"+user2.getAge()+"  user1==user2:"+(user1==user2)); //user1:18  user2:18  user1==user2:false

 五、BiFunction<T, U, R>

    /**
     * Applies this function to the given arguments.
     *
     * @param t the first function argument
     * @param u the second function argument
     * @return the function result
     */
    R apply(T t, U u);

    /**
     * Returns a composed function that first applies this function to
     * its input, and then applies the {@code after} function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of output of the {@code after} function, and of the
     *           composed function
     * @param after the function to apply after this function is applied
     * @return a composed function that first applies this function and then
     * applies the {@code after} function
     * @throws NullPointerException 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));
    }

  1、R apply(T t,U u) -- 传入参数 t,u 按照某种函数关系(有点二元方程组的意思),返回结果。

  例子:

    BiFunction<Integer,Integer,Integer> biFunction = (Integer1, Integer2) ->Integer1 * Integer2;
    Function<Integer,Integer> function = y -> y*5;
    System.out.println("结果1:"+biFunction.apply(3, 5)); //15

  2、andThen -- 用于先按照定义的biFunction执行apply以后,用前面的返回值,再按照定义的function关系执行,返回最终的结果。

  例子:

    BiFunction<Integer,Integer,Integer> biFunction = (Integer1, Integer2) ->Integer1 * Integer2;
    Function<Integer,Integer> function = y -> y*5;
    System.out.println("结果2:"+biFunction.andThen(function).apply(3,5 )); //75

六、UnaryOperator 继承自Function 该函数为一元函数,与父函数Function的区别主要在identity方法泛型上,返回值及关系都是一样的。

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

    /**
     * Returns a unary operator that always returns its input argument.
     *
     * @param <T> the type of the input and output of the operator
     * @return a unary operator that always returns its input argument
     */
    static <T> UnaryOperator<T> identity() {
        return t -> t;
    }
}

七、BinaryOperator 继承自BiFunction 二元函数,用于接收两个参数,按照某种关系(lambda表达式),执行并返回一个T类型的返回值。

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
    /**
     * Returns a {@link BinaryOperator} which returns the lesser of two elements
     * according to the specified {@code Comparator}.
     *
     * @param <T> the type of the input arguments of the comparator
     * @param comparator a {@code Comparator} for comparing the two values
     * @return a {@code BinaryOperator} which returns the lesser of its operands,
     *         according to the supplied {@code Comparator}
     * @throws NullPointerException 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;
    }

    /**
     * Returns a {@link BinaryOperator} which returns the greater of two elements
     * according to the specified {@code Comparator}.
     *
     * @param <T> the type of the input arguments of the comparator
     * @param comparator a {@code Comparator} for comparing the two values
     * @return a {@code BinaryOperator} which returns the greater of its operands,
     *         according to the supplied {@code Comparator}
     * @throws NullPointerException 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;
    }
}

  1、minBy -- 用于返回两个参数中的较小者

  例子:

    BinaryOperator binaryOperator = BinaryOperator.minBy(Comparator.naturalOrder());
    System.out.println(binaryOperator.apply(3, 4)); //3

  2、maxBy -- 用于返回两个参数中的较大者

  例子:

    BinaryOperator binaryOperator = BinaryOperator.maxBy(Comparator.naturalOrder());
    System.out.println(binaryOperator.apply(3, 4)); //4
原文地址:https://www.cnblogs.com/id-tangrenhui/p/14120893.html