zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    day91:luffy:基于vue+drf的路飞学城项目后端部署
    day90:luffy:基于vue+drf的路飞学城项目前端部署
    day89:luffy:使用Celery完成我的订单超时取消&Polyv视频加密播放
    day88:luffy:支付宝同步结果通知&接收异步支付结果&用户购买记录&我的订单
    day87:luffy:结算页面积分&支付宝接口
    day86:luffy:前端发送请求生成订单&结算页面优惠劵的实现
    day85:luffy:购物车根据有效期不同切换价格&购物车删除操作&价格结算&订单页面前戏
    C++中子类出现与父类同名成员函数如果调用父类函数
    C++继承方式引起子类中继承的父类属性访问权限的改变 && C++对象大小
    C++引用传递和指针传递区别
  • 原文地址:https://www.cnblogs.com/id-tangrenhui/p/14120893.html
Copyright © 2011-2022 走看看