子子流中列表大小的总和

时间:2017-04-23 16:41:45

标签: java java-8 java-stream

我有以下结构:

class A {
    List<B> bs;   
}

class B {
    List<C> cs;
}

class C {
    List something.
}

我有ListA类,我必须得到something列表中所有元素的汇总。我试着做以下事情:

    totalCount = as
            .stream()
            .map(a -> a.getBs()
                    .stream()
                    .mapToInt(b -> b.getSomething().size())
                    .sum());

但那不编译。我的错误在哪里?

编译错误是: Error:(61, 21) java: incompatible types: no instance(s) of type variable(s) R exist so that java.util.stream.Stream<R> conforms to java.lang.Integer

3 个答案:

答案 0 :(得分:5)

有很多方法可以获得这个结果,一种可能的方法是平放所有内容并计算结果:

A a = ..;
a.bs.stream()
  .flatMap(aa -> aa.cs.stream())
  .flatMap(bb -> bb.something.stream())
  .count();

答案 1 :(得分:2)

让这成为一个教训,为什么嵌套流是一个糟糕的想法。

你有一个映射功能:

Function<A, Integer> func = a -> a.getBs().stream()
                                          .mapToInt(b -> b.getSomething().size())
                                          .sum();

将它放在您的初始流中,然后得到:

totalCount = as
        .stream()
        .map(func);

除非totalCountStream<Integer>,否则无法编译。

答案 2 :(得分:1)

这在其他方面并不短,但至少它有测试代码来验证它是否有效。

public class NewMain {

public static void main(String[] args) {

    List<A> as = getAlist();

    int totalCount = as
            .stream()
            .map(a -> a.getBs())
            .collect(Collectors.summingInt(bs -> bs.stream()
                .map(b -> b.cs)
                .collect(Collectors.summingInt(cs -> cs.stream()
                        .map(c -> c.something)
                        .collect(Collectors.summingInt(s -> s.size()))))));
    System.out.println(totalCount);
}

private static List<A> getAlist() {
    List<A> all = new ArrayList<>();
    for (int k = 0; k < 10; k++) {
        A a = new A();
        for (int j = 0; j < 10; j++) {
            B b = new B();
            for (int i = 0; i < 10; i++) {
                C c = new C();
                c.something = Arrays.asList(1, 2, 3, 4);
                b.cs.add(c);
            }
            a.bs.add(b);
        }
        all.add(a);
    }
    return all;
}

static class A {

    List<B> bs = new ArrayList<>();

    private List<B> getBs() {
        return bs;
    }
}

static class B {

    List<C> cs = new ArrayList<>();
}

static class C {

    List something;

    List getSomething() {
        return something;
    }

}

}