• 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
  • 相关阅读:
    Java 蓝桥杯 算法训练 貌似化学
    Java 蓝桥杯 算法训练 貌似化学
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    JAVA-蓝桥杯-算法训练-字符串变换
    Ceph:一个开源的 Linux PB 级分布式文件系统
    shell 脚本监控程序是否正在执行, 如果没有执行, 则自动启动该进程
  • 原文地址:https://www.cnblogs.com/id-tangrenhui/p/14120893.html
Copyright © 2020-2023  润新知