zoukankan      html  css  js  c++  java
  • java8 函数式接口Function和BiFunction

    java8提供了函数式接口,也叫匿名函数,是我们可以定义一个方法,实现多种功能(行为传递),增强了语义(类型推演:指编译器可以自动知道某些成员的类型) 可以使我们的代码变得更加优雅!!!

    Function

    Function apply

    接口源码:

    @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);
    }
    简单的说 参数为T 返回R

    定义一个数学方法:

    public static int math(int a, Function<Integer, Integer> function) {
            int result = function.apply(a);
            return result;
    }

    调用这个方法:

    public static void main(String[] args) {
            System.out.println(math(2, value -> value + value));//求和  值为4
            System.out.println(math(2, value -> value * value));//求积  值为4
            System.out.println(math(2, value -> value - 1));//求差  值为1
    }

    可以看到  只定义了一个数学接口  却可以实现多种功能  函数式接口传递的是行为 !!!

    Function compose

     接口源码:

    public interface Function<T, R> {
        default <V> Function<V, R> compose(Function< super V, ? extends T> before) {
            Objects.requireNonNull(before);
            return (V v) -> apply(before.apply(v));
        }
    }
    接收一个Function类型的参数 把参数的执行结果给调用compose方法的function 以此来实现两个function组合

     定义一个测试方法:

    public static int test(int a, Function<Integer, Integer> funA, Function<Integer, Integer> funB) {
            return funA.compose(funB).apply(a);
    }

    调用这个方法:

     public static void main(String[] args) {
            System.out.println(test(2, value -> value - 1,value -> value * 2));//值为3
     }

    分析:源码中最后一行,先执行括号中的before.apply(v)  把他的执行结果作为参数 传入 Function<T, R>中 (这里T是V),最后执行apply(v);

    先执行funB.apply(2)  得到4  然后把4作为参数传给funA  然后执行 funcA.apply(4)  得到3

    Function andThen

     接口源码:

    public interface Function<T, R> { 
        default<V><T, V> andThen(Function<? super R, ? extends V> after) {
            Objects.requireNonNull(after);
            return (T t) -> after.apply(apply(t));
        }
    }
    接收一个Function类型的参数 先执行function本身的apply方法,执行结果作为参数 传递给 Function类型的入参after 然后执行 after的apply方法

     定义一个测试接口:

    public static int test(int a, Function<Integer, Integer> funA, Function<Integer, Integer> funB) {
            return funA.andThen(funB).apply(a);
    }

    调用这个接口:

    public static void main(String[] args) {
            System.out.println(test(2, value -> value - 1,value -> value * 2));//值为 2
    }

    分析:这个和compose刚好反过来  源码最后一行先执行括号中的appluy(t)方法 即本function的apply方法  将执行结果作为参数  在执行after.apply() 方法

    先执行 funA的apply方法  2-1得到1  然后把1作为参数 执行funB的apply方法 1*2得到2

    Function只能传递一个参数  要想传递两个参数怎么办呢? BiFunction

    BiFunction

     BiFunction apply

     接口源码:

    @FunctionalInterface
    public interface 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);
    }
    T和U都是入参 R是返回值 适用于连个参数的情况

    定义一个测试接口:

    public static int test(int a, int b, BiFunction<Integer, Integer, Integer> biFunction) {
            return biFunction.apply(a, b);
    }

    调用这个接口:

    public static void main(String[] args) {
            System.out.println(test(3, 4, (a,b) -> (a*b) - 1));//值为11
    }

    分析:挺简单的 执行两个参数运算就可以了 可以拓展为String或者其他

     BiFunction andThen

     接口源码:

    @FunctionalInterface
    public interface BiFunction<T, U, R> {
        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));
        }    
    }

     定义一个测试接口:

    public static int test(int a, int b, BiFunction<Integer, Integer, Integer> biFunction, Function<Integer, Integer> function) {
            return biFunction.andThen(function).apply(a, b);
    }

    调用这个接口:

    public static void main(String[] args) {
            System.out.println(test(4, 3, (v1, v2) -> v1 + v2, v1 -> v1 * v1));//值为 49
    }

    分析: 源码最后一行 先执行括号中的apply方法 也就是 本BiFunction的apply方法 执行4+3得7 作为参数 传给Function after 执行after得apply方法  即 7*7得49

     因为BiFunction得执行结果返回值就一个值 所以他没有 compose 甚至 andThen中跟的也不能是BiFunction 而是Function

     代码中的应用: 两个类型判断的if嵌套 甚至有4 、5种状态

    private Map<String, BiFunction<String, String, String>> getOperMap(){
            Map<String, BiFunction<String, String, String>> actionMap = new HashMap<>();
            //提交
            BiFunction<String, String, String> fun0 =  (approveType, posStatus)  -> { return "0";};
            //通过
            BiFunction<String, String, String> fun1 = (approveType, posStatus) -> {
                return approveType.equals("1")? (posStatus.equals("0")? "1": posStatus.equals("1") ? "3":null)
                        :(posStatus.equals("0")? "3" :null);
            };
            //拒绝
            BiFunction<String, String,String> fun2 = (approveType, posStatus) -> {
                return approveType.equals("1")? (posStatus.equals("0")? "": posStatus.equals("1") ? "":null)
                        :(posStatus.equals("0")? "" :null);
            };
    
            //撤回
            BiFunction<String, String, String> fun3 = (approveType, posStatus) -> {
                return "0".equals(posStatus)? "" : null;
            };
    
            actionMap.put("0", fun0);
            actionMap.put("1", fun1);
            actionMap.put("2", fun2);
            actionMap.put("3", fun3);
            return actionMap;
        }

    /**
    * 获取审核状态
    * 审批流1:空未提交 0已提交 1初审通过 2初审驳回 3终审通过 4终审驳回
    * 审批流2:空未提交 0已提交 3审批通过 4审批驳回
    *
    * 获取操作的标志 0提交 1通过 2拒绝 3撤回
    */
    //获取操作Map
    Map<String, BiFunction<String, String, String>> operMap = getOperMap();
    posStatus = operMap.get(oper).apply(approveType,posStatus);
    
    
  • 相关阅读:
    11.29 两百字
    Django:基础知识
    deepdiff:对比文件
    openpyxl:二次封装
    openpyxl:openpyxl的随笔
    web:pykeyboard、pymouse得使用
    Jmeter:如何让线程顺序执行
    Jmeter:如何将上一个线程得变量使用到下一个线程中,将上一个线程变量设置为全局变量
    Jmeter:BeanShell中的vars.put(string,string)
    Jmeter:数据库查询当天的日期
  • 原文地址:https://www.cnblogs.com/xuchao0506/p/13785581.html
Copyright © 2011-2022 走看看