最近在研究RocketMQ源码,发现很多Function和BiFunction的用法,记录一下,平时工程编码其实用得不多。
快速掌握其实只看函数实现部分就好。
不过为了方便,使用了lambda表达式。
通过本文的介绍,了解Function和BiFunction的用法。
通过函数实现整数+10,对比Function和BiFunction的区别;
public class Main {
public static class Examples {
public int add (int a,int b) {
return a+b;
}
}
public static void main(String[] args) {
System.out.println("Hello world!");
Examples res = new Examples();
System.out.println(res.add(10,10));
}
}
作为闭包,在java8中lambda作为新特性加入java。
其实当作函数就很好理解了;
举例
public class Java8Tester {
final static int b = 10;
public static void main(String args[]){
AddService addService = a -> a + b;
addService.sum(1);
}
interface AddService {
void sum(int a);
}
}
相当于实现了sum函数,参数是a,函数体是a+10;
注意Function的定义,Function
Function作为interface,其实就一个方法apply;
@FunctionalInterface
public interface Function {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
借助Function,实现整数+10;
import java.util.function.Function;
public class Main {
public static class Examples {
public int add (int a,int b) {
return a+b;
}
public int AddF(int a, Function fn) {
return fn.apply(a);
}
}
public static void main(String[] args) {
System.out.println("Hello world!");
Examples res = new Examples();
System.out.println(res.AddF(10,(a)->a+10));
}
}
其实并不复杂,这里的fn.apply(a)可以简单理解下就是Lambda函数的执行先后问题,将a传入lambda函数,然后执行并返回结果;apply(a)可以理解为将a作为参数传入lambda的操作,并触发lambda;
public int AddF(int a, Function fn) {
return fn.apply(a);
}
相比Function更复杂;
对比Function的实现,多了一个function before;注意调用链(V v)->apply(before);
public interface Function {
default Function compose(Function super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
}
实现整数+10,多的函数实现乘积,方便测试和对比;
import java.util.function.Function;
public class Main {
public static class Examples {
public int add (int a,int b) {
return a+b;
}
public int AddF(int a, Function fn) {
return fn.apply(a);
}
public int AddFC(int a, Function fn1,Function fn2) {
return fn1.compose(fn2).apply(a);
}
}
public static void main(String[] args) {
System.out.println("Hello world!");
Examples res = new Examples();
System.out.println(res.AddFC(10,(a)->a+10,(b)->b*5));
}
}
这是因为Function Compose相比Function多了Function fn2,先执行fn2中的逻辑,然后将结果传递给fn1;
如果用Function来解释就是:
50 = fn2.apply(10)
然后执行fn1.apply(50);也就是得到结果60。这里fn1与fn2的先后顺序非常重要。
了解了前面的内容其实可以发现,重点是多个function的执行顺序问题;来到Function AndThen也是同理;
先执行fn1,然后执行fn2;
public interface Function {
default Function andThen(Function super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
}
import java.util.function.Function;
public class Main {
public static class Examples {
public int add (int a,int b) {
return a+b;
}
public int AddF(int a, Function fn) {
return fn.apply(a);
}
public int AddFC(int a, Function fn1,Function fn2) {
return fn1.compose(fn2).apply(a);
}
public int AddFAT(int a, Function fn1,Function fn2) {
return fn1.andThen(fn2).apply(a);
}
}
public static void main(String[] args) {
System.out.println("Hello world!");
Examples res = new Examples();
System.out.println(res.AddFAT(10,(a)->a+10,(b)->b*5));
}
}
相较来说理解andThen就简单多了,先执行fn1.apply(10),得到结果20;然后执行fn2.apply(20);输出100。
理解了Function,那么理解BiFunction就简单很多;
BiFunction是Function多带了一个参数;也就是说如果想向Function传入2个参数那么就需要BiFunction;
@FunctionalInterface
public interface BiFunction {
R apply(T t, U u);
default BiFunction andThen(Function super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}
借助BiFunction实现两数相加;
import java.util.function.BiFunction;
import java.util.function.Function;
public class Main {
public static class Examples {
public int add (int a,int b) {
return a+b;
}
public int AddF(int a, Function fn) {
return fn.apply(a);
}
public int AddFC(int a, Function fn1,Function fn2) {
return fn1.compose(fn2).apply(a);
}
public int AddFAT(int a, Function fn1,Function fn2) {
return fn1.andThen(fn2).apply(a);
}
public int AddBiF(int a,int b, BiFunction fn1) {
return fn1.apply(a,b);
}
}
public static void main(String[] args) {
System.out.println("Hello world!");
Examples res = new Examples();
System.out.println(res.AddBiF(10,10,(a,b)->a+b));
}
}
其实就是Function多加了一个参数,理解了Function那么BiFunction就很容易理解了。