我想对一个整数列表求和。它的工作原理如下,但是语法感觉不太对。代码可以优化吗?
Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();
我想对一个整数列表求和。它的工作原理如下,但是语法感觉不太对。代码可以优化吗?
Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).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);
其他回答
来自文档
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);
我建议另外两种选择:
integers.values().stream().mapToInt(Integer::intValue).sum();
integers.values().stream().collect(Collectors.summingInt(Integer::intValue));
第二个使用collections . summingint()收集器,还有一个summingLong()收集器,您可以将其与mapToLong一起使用。
第三个选择:Java 8引入了非常有效的LongAdder累加器,旨在加快并行流和多线程环境中的汇总速度。这里有一个例子:
LongAdder a = new LongAdder();
map.values().parallelStream().forEach(a::add);
sum = a.intValue();
这将工作,但i -> i正在做一些自动开箱,这就是为什么它“感觉”奇怪。mapToInt将流转换为“原始int值元素”的IntStream。下面的任何一个都可以工作,并且更好地解释编译器在你的原始语法下所做的事情:
integers.values().stream().mapToInt(i -> i.intValue()).sum();
integers.values().stream().mapToInt(Integer::intValue).sum();
你可以使用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);
可以使用collect方法添加整数列表。
List<Integer> list = Arrays.asList(2, 4, 5, 6);
int sum = list.stream().collect(Collectors.summingInt(Integer::intValue));