如何用java流对整数列表求和?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30125296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to sum a list of integers with java streams?
提问by membersound
I want to sum a list of integers. It works as follows, but the syntax does not feel right. Could the code be optimized?
我想总结一个整数列表。它的工作原理如下,但语法感觉不对。代码可以优化吗?
Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();
采纳答案by Necreaux
This will work, but the i -> i
is doing some automatic unboxing which is why it "feels" strange. Either of the following will work and better explain what the compiler is doing under the hood with your original syntax:
这会起作用,但它i -> i
正在做一些自动拆箱,这就是为什么它“感觉”很奇怪。以下任一方法都可以使用并更好地解释编译器在使用您的原始语法进行的工作:
integers.values().stream().mapToInt(i -> i.intValue()).sum();
integers.values().stream().mapToInt(Integer::intValue).sum();
回答by J Atkin
From the docs
从文档
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);
归约运算 归约运算(也称为折叠)采用一系列输入元素,并通过重复应用组合运算将它们组合成单个汇总结果,例如求一组数字的总和或最大值,或将元素累加为一个列表。流类具有多种形式的通用归约操作,称为reduce() 和collect(),以及多种特殊归约形式,如sum()、max() 或count()。
当然,这样的操作可以很容易地实现为简单的顺序循环,如:
int sum = 0; for (int x : numbers) { sum += x; }
然而,有充分的理由更喜欢减少操作而不是像上面那样的突变累积。不仅reduce“更抽象”——它作为一个整体而不是单个元素对流进行操作——而且一个正确构造的reduce操作本质上是可并行化的,只要用于处理元素的函数是关联的和无国籍。例如,给定一个我们想要求和的数字流,我们可以这样写:
int sum = numbers.stream().reduce(0, (x,y) -> x+y);
或者:
int sum = numbers.stream().reduce(0, Integer::sum);
这些归约操作几乎不需要修改就可以安全地并行运行:
int sum = numbers.parallelStream().reduce(0, Integer::sum);
So, for a map you would use:
因此,对于地图,您将使用:
integers.values().stream().mapToInt(i -> i).reduce(0, (x,y) -> x+y);
Or:
或者:
integers.values().stream().reduce(0, Integer::sum);
回答by Alex Salauyou
I suggest 2 more options:
我建议另外 2 个选项:
integers.values().stream().mapToInt(Integer::intValue).sum();
integers.values().stream().collect(Collectors.summingInt(Integer::intValue));
The second one uses Collectors.summingInt()
collector, there is also a summingLong()
collector which you would use with mapToLong
.
第二个使用Collectors.summingInt()
收集器,还有一个summingLong()
收集器可以与mapToLong
.
And a third option: Java 8 introduces a very effective LongAdder
accumulator designed to speed-up summarizing in parallel streams and multi-thread environments. Here, here's an example use:
第三个选项:Java 8 引入了一个非常有效的LongAdder
累加器,旨在加速并行流和多线程环境中的汇总。在这里,这是一个使用示例:
LongAdder a = new LongAdder();
map.values().parallelStream().forEach(a::add);
sum = a.intValue();
回答by Saeed Zarinfam
You can use reduce method:
您可以使用减少方法:
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);
回答by Ashish Jha
You can use collect method to add list of integers.
您可以使用 collect 方法添加整数列表。
List<Integer> list = Arrays.asList(2, 4, 5, 6);
int sum = list.stream().collect(Collectors.summingInt(Integer::intValue));
回答by Johnson Abraham
You can use reduce()
to sum a list of integers.
您可以使用reduce()
对整数列表求和。
int sum = integers.values().stream().reduce(0, Integer::sum);
回答by Ranjit Soni
class Pojo{
int num;
public Pojo(int num) {
super();
this.num = num;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
List<Pojo> list = new ArrayList<Pojo>();
list.add(new Pojo(1));
list.add(new Pojo(5));
list.add(new Pojo(3));
list.add(new Pojo(4));
list.add(new Pojo(5));
int totalSum = list.stream().mapToInt(pojo -> pojo.getNum()).sum();
System.out.println(totalSum);
回答by ManojG
Most of the aspects are covered. But there could be a requirement to find the aggregation of other data types apart from Integer, Long(for which specialized stream support is already present). For e.g. stram with BigInteger For such a type we can use reduce operation like
涵盖了大部分方面。但是可能需要找到除 Integer、Long(已经存在专门的流支持)之外的其他数据类型的聚合。例如,带有 BigInteger 的 stram 对于这种类型,我们可以使用 reduce 操作,例如
list.stream().reduce((bigInteger1, bigInteger2) -> bigInteger1.add(bigInteger2))
list.stream().reduce((bigInteger1, bigInteger2) -> bigInteger1.add(bigInteger2))
回答by Sachith Dickwella
This would be the shortest way to sum up int
type array (for long
array LongStream
, for double
array DoubleStream
and so forth). Not all the primitive integer or floating point types have the Stream
implementation though.
这将是总结int
类型数组的最短方法(对于long
数组LongStream
,对于double
数组DoubleStream
等等)。并非所有原始整数或浮点类型都有Stream
实现。
IntStream.of(integers).sum();
回答by JDGuide
I have declared a list of Integers.
我已经声明了一个整数列表。
ArrayList<Integer> numberList = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
You can try using these different ways below.
您可以尝试使用以下这些不同的方法。
Using mapToInt
使用 mapToInt
int sum = numberList.stream().mapToInt(Integer::intValue).sum();
Using summarizingInt
使用 summarizingInt
int sum = numberList.stream().collect(Collectors.summarizingInt(Integer::intValue)).getSum();
Using reduce
使用 reduce
int sum = numberList.stream().reduce(Integer::sum).get().intValue();