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