Java Lambda 对单个流的多个操作

Pra*_*nay 5 java lambda

场景:我有一个具有 2 个函数的对象 -->

<Integer> getA(); <Integer> getB();
Run Code Online (Sandbox Code Playgroud)

我有一个对象列表,比如说List<MyObject> myObject

目标迭代列表并获得对象列表中 A 和 B 的总和。

我的解决方案

myObject.stream().map(a -> a.getA()).collect(Collectors.summingDouble());

myObject.stream().map(a -> a.getB()).collect(Collectors.summingDouble());
Run Code Online (Sandbox Code Playgroud)

问题:我怎样才能同时做到这两点?这样我就不必在原始列表上迭代两次。

@Edit:我这样做是因为我使用的一些过滤器是 O(n^3)。做两次真的很糟糕。

基准:当程序在 i5 上运行半小时时,它是 T 还是 2T 真的很重要。这是基于更少的数据,如果我在集群上运行,我的数据也会更大。

如果您可以在一行中完成这些,那很重要!

Che*_*hen 3

您需要编写另一个类来存储总值,如下所示:

public class Total {
    private int totalA = 0;
    private int totalB = 0;

    public void addA(int a) {
        totalA += a;
    }

    public void addB(int b) {
        totalB += b;
    }

    public int getTotalA() {
        return totalA;
    }

    public int getTotalB() {
        return totalB;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后使用收集值

Total total = objects.stream()
        .map(o -> (A) o)
        .collect(Total::new,
                (t, a) -> {
                    t.addA(a.getA());
                    t.addB(a.getB());
                },
                (t1, t2) -> { });
//check total.getTotalA() and total.getTotalB()
Run Code Online (Sandbox Code Playgroud)

您还可以使用AbstractMap.SimpleEntry<Integer, Integer>替换Total来避免编写新类,但这仍然有点奇怪,因为 A/B 不是键值关系。