我想对一个整数列表求和。它的工作原理如下,但是语法感觉不太对。代码可以优化吗?

Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();

当前回答

这里还有一个没有考虑到的选项,它反映了多核环境的使用。如果你想利用它的优势,那么应该使用下面的代码,而不是其他提到的解决方案:

int sum = integers.values().parallelStream().mapToInt(Integer::intValue)
        .reduce(0, Integer::sum, Integer::sum);

This solution is similar to other ones, but please notice the third argument in reduce. It tells compiler what to do with partial summaries calculated in different chunks of the stream, by different threads. Also instead of stream(), the parallelStream() is used. In this case it would just summarize it. The other option to put as third argument is (i, j) -> i + j, which means that it would add a value of a stream chunk (j) to the current value (i) and use it as a current value for the next stream chunk until all partial results are processed.

即使在使用普通的stream()时,告知如何减少对流块的摘要的处理也是有用的,以防将来有人(或您)想要并行化它。最初的开发是最好的时间,因为之后你需要记住这应该是什么,需要花一些时间来再次理解代码的目的。

当然,除了方法引用运算符,你可以用不同的方言。我更喜欢这种方式,因为它更紧凑,而且仍然易于阅读。

还要记住,这也可以用于更复杂的计算,但始终要注意,不能保证流元素到线程的顺序和部署。

其他回答

IntStream.of(1, 2, 23).sum();
IntStream.of(1, 2, 23,1, 2, 23,1, 2, 23).max().getAsInt();

你可以使用reduce方法:

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, (x, y) -> x + y);

or

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, Integer::sum);

来自文档

Reduction operations A reduction operation (also called a fold) takes a sequence of input elements and combines them into a single summary result by repeated application of a combining operation, such as finding the sum or maximum of a set of numbers, or accumulating elements into a list. The streams classes have multiple forms of general reduction operations, called reduce() and collect(), as well as multiple specialized reduction forms such as sum(), max(), or count(). Of course, such operations can be readily implemented as simple sequential loops, as in: int sum = 0; for (int x : numbers) { sum += x; } However, there are good reasons to prefer a reduce operation over a mutative accumulation such as the above. Not only is a reduction "more abstract" -- it operates on the stream as a whole rather than individual elements -- but a properly constructed reduce operation is inherently parallelizable, so long as the function(s) used to process the elements are associative and stateless. For example, given a stream of numbers for which we want to find the sum, we can write: int sum = numbers.stream().reduce(0, (x,y) -> x+y); or: int sum = numbers.stream().reduce(0, Integer::sum); These reduction operations can run safely in parallel with almost no modification: int sum = numbers.parallelStream().reduce(0, Integer::sum);

所以,对于一个地图,你会使用:

integers.values().stream().mapToInt(i -> i).reduce(0, (x,y) -> x+y);

Or:

integers.values().stream().reduce(0, Integer::sum);

这里还有一个没有考虑到的选项,它反映了多核环境的使用。如果你想利用它的优势,那么应该使用下面的代码,而不是其他提到的解决方案:

int sum = integers.values().parallelStream().mapToInt(Integer::intValue)
        .reduce(0, Integer::sum, Integer::sum);

This solution is similar to other ones, but please notice the third argument in reduce. It tells compiler what to do with partial summaries calculated in different chunks of the stream, by different threads. Also instead of stream(), the parallelStream() is used. In this case it would just summarize it. The other option to put as third argument is (i, j) -> i + j, which means that it would add a value of a stream chunk (j) to the current value (i) and use it as a current value for the next stream chunk until all partial results are processed.

即使在使用普通的stream()时,告知如何减少对流块的摘要的处理也是有用的,以防将来有人(或您)想要并行化它。最初的开发是最好的时间,因为之后你需要记住这应该是什么,需要花一些时间来再次理解代码的目的。

当然,除了方法引用运算符,你可以用不同的方言。我更喜欢这种方式,因为它更紧凑,而且仍然易于阅读。

还要记住,这也可以用于更复杂的计算,但始终要注意,不能保证流元素到线程的顺序和部署。

可以使用reduce()对整数列表求和。

int sum = integers.values().stream().reduce(0, Integer::sum);