使用流API在Java中如何找到对象列表中多个字段的总和?

huangapple go评论65阅读模式
英文:

In Java, how to find the sum of several fields in a list of objects using stream API?

问题

以下是已翻译的代码部分:

List<Object> objectList = new ArrayList<>();
objectList.add(new Object(X1="ABC", X2=1, X3=3));
objectList.add(new Object(X1="XYZ", X2=2, X3=7));
objectList add(new Object(X1="AC", X2=1, X3=3));
objectList add(new Object(X1="AB", X2=1, X3=3));

int X2Sum = objectList.stream().mapToInt(o -> o.getX2()).sum();
int X3Sum = objectList.stream().mapToInt(o -> o.getX3()).sum();
英文:

As shown below, I have a list of objects with integer fields like X2 and X3.

List&lt;Object&gt; objectList=new ArrayList&lt;&gt;();
objectList.add(new Object(X1=&quot;ABC&quot;,X2=1,X3=3));
objectList.add(new Object(X1=&quot;XYZ&quot;,X2=2,X3=7));
objectList.add(new Object(X1=&quot;AC&quot;,X2=1,X3=3));
objectList.add(new Object(X1=&quot;AB&quot;,X2=1,X3=3));

The goal is to navigate through this list and get the sum of all X2s and X3s.

I attempted the method below to calculate the sum, but I believe there should be a way to do it with one stream() call.

int X2Sum=objectList.stream().mapToInt(o-&gt;o.getX2()).sum();
int X3Sum=objectList.stream().mapToInt(o-&gt;o.getX3()).sum();

答案1

得分: 2

IntStream.sum() 终端只返回流的一个单一总和。

这意味着您需要两个单独的流来获取两个总和,就像您已经有的那样:

int sumOfX2 = objectList.stream().mapToInt(o -> o.getX2()).sum();
int sumOfX3 = objectList.stream().mapToInt(o -> o.getX3()).sum();

只使用一个流的替代方法需要一个 reduce 步骤,如 https://stackoverflow.com/questions/50582475/reduce-operation-on-custom-object-in-java 中所解释的。

List<Pojo> pojoList = new ArrayList<>();
pojoList.add(new Pojo("ABC", 1, 3));
pojoList add(new Pojo("XYZ", 2, 7));

var pojoSum = pojoList.stream().reduce(
  new Pojo("sumX", 0, 0), // 初始结果
  // 组合器已经是累加器
  (pojoResult, pojoToAdd) -> {
    pojoResult.setX2(pojoResult.getX2() + pojoToAdd.getX2());
    pojoResult.setX3(pojoResult.getX3() + pojoToAdd.getX3());
    return pojoResult;
  }
);

参见:
https://www.baeldung.com/java-stream-sum

英文:

The IntStream.sum() terminal only returns one single sum per stream.
This means you need two separate streams for two sums like you already have:

int sumOfX2 = objectList.stream().mapToInt(o-&gt;o.getX2()).sum();
int sumOfX3 = objectList.stream().mapToInt(o-&gt;o.getX3()).sum();

An alternative way with only using one stream would require a reduce step as explained in https://stackoverflow.com/questions/50582475/reduce-operation-on-custom-object-in-java.

List&lt;Pojo&gt; pojoList = new ArrayList&lt;&gt;();
pojoList.add(new Pojo(&quot;ABC&quot;, 1, 3));
pojoList.add(new Pojo(&quot;XYZ&quot;, 2, 7));

var pojoSum = pojoList.stream().reduce(
  new Pojo(&#168;sumX&#168; 0,0), // initial result
  // the combiner is already the accumulator
  (pojoResult, pojoToAdd) -&gt; {
    pojoResult.setX2( pojoResult.getX2() + pojoToAdd.getX2() );
    pojoResult.setX3( pojoResult.getX3() + pojoToAdd.getX3() );
    return pojoResult;
  }
);

See also:
https://www.baeldung.com/java-stream-sum

huangapple
  • 本文由 发表于 2023年2月14日 02:47:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75440052.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定