以下代码段无法编译。如下所示,如何使用sum
查找forEach
?
private int Sum(ArrayList<Integer> inputs) {
int sum = 0;
inputs.stream().forEach(x -> sum += x);
return sum;
}
答案 0 :(得分:5)
这应该可以解决问题:
private int Sum(ArrayList<Integer> inputs) {
return inputs.stream().mapToInt(Integer::intValue).sum();
}
编辑:
使用for-each
的问题在于它是一个终端操作,这意味着它不会产生另一个中间流供我们处理。更好的方法是使用mapToInt
,它会产生一个IntStream
,我们可以在上面轻松地找到总和。
答案 1 :(得分:2)
这个答案只是为了提供更多有关代码为什么不起作用的背景信息,从而使您可以在将来发生问题时对问题进行解读。
您似乎是.NET用户,因此完全可以理解您所编写的代码可以正常工作。在.NET中,等效项为:
private int Sum(List<int> inputs) {
int sum = 0;
inputs.ForEach(x => sum += x);
return sum;
}
但是,在Java中,lambda表达式中使用的变量必须为final或effectively final,因此,inputs.stream().forEach(x -> sum += x);
语句将无法编译。
尽管如此,仅仅因为人们期望上述代码可以在C#中工作并不一定意味着它应该在Java中工作,因为存在不同的规则。
有些解决方案可以使用forEach
方法来找到一组数字的总和,但这不是惯用方法,因此除非有必要,否则应避免使用。
惯用的方法就像@Nicholas K所示。
另一方面:
return inputs.Sum();
而不是使用ForEach
扩展方法对给定列表的元素求和。inputs.stream().forEach(...);
时,都应该改为inputs.forEach(...)
,因为所有列表都有forEach
方法。