这是编译器的一个角落.为了确定是否应用将参数包装到数组中或简单地传递数组,它需要知道最后一个参数的类型,然而,在lambda表达式的情况下,它需要调用方法签名来确定类型.但是很明显,应该发生什么,因为lambda表达式永远不会是数组类型,所以javac编译它没有问题.
一个可以接受的解决办法是超载方法:
@SafeVarargs
public static Stream filter(Stream source, Predicate... predicates) {
return source.filter(
Arrays.stream(predicates).reduce(predicates[0], Predicate::and));
}
public static Stream filter(Stream source, Predicate predicate) {
return source.filter(predicate);
}
这将是一个可以接受的解决方案,因为它不需要任何改变的呼叫方,同时提高单一案件的效率在同一时间.
请注意,您的varargs方法允许零参数,但如果以这种方式调用将失败.所以你应该添加另一个超负荷:
public static Stream filter(Stream source) {
return source;
}
或使方法对于零参数情况是安全的:
@SafeVarargs
public static Stream filter(Stream source, Predicate... predicates) {
return Arrays.stream(predicates).reduce(Predicate::and)
.map(source::filter).orElse(source);
}