Java流在减少操作的情况下给出语法错误

jav*_*456 1 java java-8 java-stream

我试图在Integer流上使用reduce方法来获取所有值的总和。但出现语法错误,无法找出错误。

List<Integer> ee = new ArrayList<Integer>();
Function<? super Integer, ? extends Integer> f3 = x -> x / 2;
BinaryOperator<? extends Integer> accumulator = (x, y) -> x + y;
ee.stream().map(f3).reduce(new Integer(0), accumulator);
Run Code Online (Sandbox Code Playgroud)

它给出了错误:

The method reduce(capture#2-of ? extends Integer, BinaryOperator<capture#2-of ? extends Integer>) in the type Stream<capture#2-of ? extends Integer> is not applicable for the arguments (Integer, BinaryOperator<capture#7-of ? extends Integer>)
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

问题在于您所到达的所有边界。虽然它会带我一段时间才能出来(再解释)正是编译器认为正在发生的事情,这是如果你只是改变一切使用具体类型...毕竟要简单得多,它不是像这实在是一个“扩展整数但无法确定的事物”。它们只是整数。该代码可以很好地编译,并且也更容易理解。

Function<Integer, Integer> f3 = x -> x / 2;
BinaryOperator<Integer> accumulator = (x, y) -> x + y;
int result = ee.stream().map(f3).reduce(Integer.valueOf(0), accumulator);
Run Code Online (Sandbox Code Playgroud)

如注释中所述,自动装箱和方法引用的使用可以显着简化最后一行(并消除了对accumulator变量的需要):

int result = ee.stream().map(f3).reduce(0, Integer::sum);
Run Code Online (Sandbox Code Playgroud)

第一个代码段保留了问题的更多结构,因此更易于适应其他累加器功能。

  • 实际上非常简单。像`BinaryOperator &lt;?这样的声明。extended Integer&gt; accumulator`指定输入类型为* unknown *。我们所知道的是它是Integer的某种子类型,但是我们不知道是哪一种,这使得该功能完全无法使用。另一个功能遵循[PECS规则](/sf/ask/190637821/),这很好,但是编译器需要一些帮助,例如`。&lt;Integer&gt; map(f3)`。顺便说一句,不需要手动装箱,`reduce(0,accumulator)`或仅`reduce(0,Integer :: sum)都可以。 (2认同)