流减少不兼容的类型

stream reduction incompatible types

我正在尝试创建一个查找器,它接受多个谓词并减少它们:

public static <T extends BusinessInterface> Collection<T> findOr(
    Context pContext, Class<T> pClass, Predicate<? super T>... pPredicates) {
  Predicate<? super T> lReducedPredicate =
      Arrays.asList(pPredicates).stream().reduce(Predicate::or).orElse(r -> false);
  return find(pContext, pClass, lReducedPredicate);
}

不幸的是,我得到以下编译器错误:

Predicate lReducedPredicate = Arrays.asList(pPredicates).stream().reduce(Predicate::or).orElse(r -> false); incompatible types: Predicate cannot be converted to Predicate where T is a type-variable: T extends BusinessInterface declared in method findOr(Context,Class,Predicate...) where CAP#1,CAP#2 are fresh type-variables: CAP#1 extends Object super: T from capture of ? super T CAP#2 extends Object super: T from capture of ? super T

我在 Eclipse 中没有错误,我也不知道出了什么问题。

非常感谢任何帮助:)。

你的代码在 intellij 中对我有用,但在 ideone 中却不行,这很奇怪。

编译器错误的原因是您实际上是在尝试这样做:

Predicate<? super T> a = null;
Predicate<? super T> b = null;
a.or(b);  // Compiler error!

由于 ab 上的单独通配符,编译器无法保证类型边界兼容,因为这些通配符不一定相同。

无论如何,试试这个奇怪的技巧:

Arrays.asList(pPredicates)
    .stream()
    .map(a -> a)  // Here!
    .reduce(Predicate::or)
    .orElse(r -> false);

插入这一行允许它转换为与类型约束相匹配的类型。

解决这个问题的一种方法是使用

public static <T extends BusinessInterface> Collection<T> findOr(
    Context pContext, Class<T> pClass, Predicate<? super T>... pPredicates) {
  Predicate<? super T> lReducedPredicate = Arrays.asList(pPredicates).stream()
    .reduce((a,b) -> t -> a.test(t) || b.test(t)).orElse(r -> false);
  return find(pContext, pClass, lReducedPredicate);
}

虽然您不能在 Predicate<? super T> 实例上以另一个 Predicate<? super T> 作为参数调用 or 方法,但您可以创建相同的函数,or 会 return,你自己,因为将 T 实例传递给任一 test 方法都是有效的。