Java-SE-8之Function分析

Scroll Down
@FunctionalInterface注解

提供该注解是为了让被标识的接口可以应用在lambda表达式上。被该注解修饰的接口只允许有一个抽象方法,也叫做Single Abstract Method Interface但是可内部有多个default方法。也可以重写Object的方法,还可以有静态方法。Java SE 8提供了如下ConsumerPredicateFunctionSupplierUnaryOperatorBinaryOperator类。@FunctionalInterface注解是一个用于编译时期检查的注解。如果你定义的接口中含有多个抽象方法则不符合校验规则,IDE会提示错误。

Function<T,R>

将Function对象应用到输入的参数上,然后返回计算结果。接收T对象,返回R对象,相当于一个方法,常用的就是apply方法,高阶使用可以配合andThen和compose方法实现方法的柯里化(函数多层嵌套)。虽然java 8支持了OO和FP,但是FP方面还是没有Scala做的好。

Function<Map<String,String>,List<DemoClass>> query= x->{
        EntityWrapper<demoClassService> queryWrapper = new EntityWrapper<>();
        x.forEach(queryWrapper::eq);
        queryWrapper.eq(demoClassService.DELETED, demoClassService.STATUS_UN_DELETE);
        return Optional.ofNullable(demoClassService.selectList(queryWrapper)).orElse(new LinkedList<DemoClass>());
    };
    query.apply(new HashMap<String, String>(){{put("key","value");}});

高阶使用使用andThen表示在apply之后作操作该Function的返回值是andThen里的function的入参。

query.andThen(x -> x.stream().map(y -> y.getId()).collect(Collectors.toList())).apply(new HashMap<String, String>(){{put("key","value");}});

高阶使用使用compose表示在原function执行apply之前先执行compose里的function然后返回值作为原function执行apply的入参。

Map request=new HashMap<String, String>(){{put("key","value");}};
query.compose(x -> {x.put("key","value");return x).apply(request);
Consumer<T>

相当与一个void方法,接收T对象,不返回值,Consumer<T>也有addThen默认方法,和Function<T,R>一样这里就不再重复说。主要是看下accept方法.

Consumer<String> consumer=x->{
          if (x.equals("consumer")){
              System.out.println("invoke success");
          }
        };
consumer.accept("consumer");
// output:invoke success
Predicate<T>

Function<T,R>不一样的是该接口是接收T对象并返回boolean。Predicate<T>其中的是test方法。高阶使用有配合andornegate三个default方法来实现条件函数的柯里化。

        Predicate<String> predicate=x-> x.equals("predicate")?true:false;
        System.out.println("invoke success predicate result: "+predicate.test("consumer"));
        // output:invoke success predicate result: false

Supplier<T>

这个接口比较有意思是一个工厂接口,单纯的制作T对象只有一个get方法

 Supplier<String> supplier=()-> "consumer";
 consumer.accept(supplier.get());
 // output:invoke success
UnaryOperator<T>

这个接口继承自Function<T,R>内部有只有一个静态方法,场景使用在入参和结果属于同一类型的情况。也就是一元运算符

  UnaryOperator<String> unaryOperator=x-> x.substring(0,3);
        unaryOperator.apply("consumer");
        System.out.println("invoke success unaryOperator result: "+unaryOperator.apply("consumer"));
        // output:invoke success unaryOperator result: con
BinaryOperator<T>

这个接口继承自BiFunction<<T, U, R>内部有只有二个静态方法minBy和maxBy并且这俩个方法的入参必须是实现了Comparator接口的类对象才可以,场景使用在入参和结果属于同一类型的情况。也就是二元运算符

 BinaryOperator<Long> binaryOperator=(x,y)-> x*y;
        System.out.println("invoke success binaryOperator result: "+binaryOperator.apply(3L,4L));
        // output:invoke success binaryOperator result: 12
BiFunction<<T, U, R>

看了上述的BinaryOperator<T> 我想你肯定知道了BiFunction<<T, U, R> 是干啥的,输入二个入参(T,U)得到返回值R。这是java在函数二个参数的默认的实现,再多的参数列表java没有默认支持了,并没有像RxJava系列中提供到Fun9。但是你也是可以自己实现N个参数的函数式接口。

@FunctionalInterface
public interface LOLFunction<Q,W,E,R,D,F,A> {
    
    A apply(Q q,W w,E e,R r,D d,F f);
}
LOLFunction<Q,W,E,R,D,F,A> ruiwen=(q,w,e,r,d,f)->{
	return new A("victory");
};
ruiwen.apply(折翼之舞,震魂怒吼,勇往直前,放逐之锋,闪现,点燃);

image