Как рассчитать суммирование свойства в структуре вложенного класса в Java 8? - PullRequest
0 голосов
/ 28 мая 2018

У меня есть 3 класса, класс A, B, C. Класс A содержит список класса B, класс B содержит список класса C. Класс C содержит примитивы.

class A {
    List<B> bList;
//getter
}

class B {
    List<C> cList;
//getter
}

class C {
    int a;
    int b;
    int c;
//getter
}

Я хочу сделатьследующий.

A aInstance = new A();
List<B>bs = aInstance.getBList();
for(B b: bs) {
        List<C> cs = b.getCList();
        for(C c: cs) {
            sum_a += c.a;
            sum_b_c += c.b + c.c;
        }
    }

Как я могу добиться этого с java 8 определенных потоков?

Ответы [ 5 ]

0 голосов
/ 28 мая 2018

Я бы не стал использовать потоки в этом конкретном случае, так как вы ничего от этого не получите.на самом деле, при использовании потока кода гораздо больше, он не так удобен для чтения, как можно подумать, и не так эффективен, как императивный цикл for.

Итак, я бы посоветовал вам продолжить работу с текущимподход и на самом деле, вы можете уменьшить код, который вы в настоящее время должны:

for(B b: aInstance.getBList()) {
    for(C c: b.getCList()) {
       sum_a += c.a;
       sum_b_c += c.b + c.c;
    }
}
0 голосов
/ 28 мая 2018

Ну, на шаге collect должен быть шаг flatMap и соответствующий аккумулятор, например:

int[] sums = a.bList.stream().flatMap(b -> b.cList.stream())
    .collect(() -> new int[2], (acc, v) -> {
               acc[0] += v.a;
               acc[1] += v.b + v.c;
             }, (acc, other) -> {
               acc[0] += other[0];
               acc[1] += other[1];
             }); 
0 голосов
/ 28 мая 2018

Вам понадобится какой-то тип для хранения двух сумм, например:

public class Sums {
    int sumA;
    int sumBC;
    public Sums (int sumA, int sumBC) {this.sumA=sumA; this.sumBC=sumBC;}
    public int getA() {return sumA;}
    public int getBC() {return sumBC;}
}

Теперь вы создаете Stream элемента, который хотите суммировать, и уменьшаете его до экземпляра Sums:

Sums sums = aInstance.getBList()
                     .stream()
                     .flatMap(b->b.getCList().stream())
                     .reduce(new Sums(0,0),
                            (s,c)->new Sums(s.getA()+c.getA(),s.getBC()+c.getB()+c.getC()),
                            (s1,s2)->new Sums(s1.getA()+s2.getA(),s1.getBC()+s2.getBC()));
0 голосов
/ 28 мая 2018

Вы можете reduce передать это в массив int, например, с двумя элементами:

int[] result = aInstance
            .getBList()
            .stream()
            .flatMap(b -> b.getcList().stream())
            .map(c -> new int[] { c.a, c.b + c.c })
            .reduce((left, right) -> {
                int[] newV = new int[2];
                newV[0] = left[0] + right[0];
                newV[1] = left[1] + right[1];
                return newV;
            })
            .orElse(new int[] { 0, 0 });

Или даже лучше через collect (не создавать много int [] объектов):

int[] result = aInstance
            .getBList()
            .stream()
            .flatMap(b -> b.getCList().stream())
            .collect(
                    () -> new int[2],
                    (arr, c) -> {
                        arr[0] += c.a;
                        arr[1] += c.b + c.c;
                    }, 
                    (left, right) -> {
                        left[0] += left[0];
                        right[1] += right[1];
                    });
0 голосов
/ 28 мая 2018

Попробуйте,

final int sumOfAs = aInstance.getbList()
                    .stream()
                    .map(b -> b.getcList())
                    .flatMap(List::stream)
                    .mapToInt(C::getA)
                    .sum();

Чтобы получить сумму B, C s, она должна быть такой:

final int sumOfBCs = aInstance.getbList()
                       .stream()
                       .map(b -> b.getcList())
                       .flatMap(List::stream)
                       .mapToInt(c -> c.getB() + c.getC())
                       .sum();

ОБНОВЛЕНИЕ:

Если вы действительно хотите вычислить их оба одновременно, вы можете сделать это следующим образом:

C sumOfValues = aInstance.getbList()
                  .stream()
                  .map(b -> b.getcList())
                  .flatMap(List::stream)
                  .reduce(new C(0, 0, 0), (c1, c2) -> {
                    return new C(c1.getA() + c2.getA(), c1.getB() + 
                                 c2.getB(), c1.getC() + c2.getC());
                    });


System.out.println("Sum of As: " + sumOfValues.getA() + " Sum of BCs: "
        + Integer.sum(sumOfValues.getB(), sumOfValues.getC()));
...