@FunctionalInterface注解
提供该注解是为了让被标识的接口可以应用在lambda表达式上。被该注解修饰的接口只允许有一个抽象方法,也叫做
Single Abstract Method Interface
但是可内部有多个default
方法。也可以重写Object的方法,还可以有静态方法。Java SE 8提供了如下Consumer
,Predicate
,Function
,Supplier
,UnaryOperator
,BinaryOperator
类。@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方法。高阶使用有配合and
,or
,negate
三个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(折翼之舞,震魂怒吼,勇往直前,放逐之锋,闪现,点燃);