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

 

posted @ 2020-10-09 18:35  ジ绯色月下ぎ  阅读(318)  评论(0编辑  收藏  举报