Ваше направление правильное. Единственное, что нужно сделать, это последний шаг, который объединяет все номера продаж в один объект. Вы не можете просто использовать summingInt
, потому что он возвращает только int, а у вас нет других полей для создания объекта. Вы можете добиться этого, используя reduce
для создания начального объекта и добавляя значение поля:
list.stream()
.collect(groupingBy(Sale::getState,
groupingBy(Sale::getCity,
reducing( (a, b) -> new Sale(a.getMonth(), a.getYear(), a.getState(), a.getCity(), a.getSale() + b.getSale()) ))));
Если вам не важны месяц и год, вы также можете создать объект идентификации (начальный объект ) и добавить к нему только продажи. Это может уменьшить количество создаваемых временных объектов:
list.stream()
.collect(groupingBy(Sale::getState,
groupingBy(Sale::getCity,
reducing(new Sale("Total", "2000", "", "", 0), (a, b) -> {
a.setState(b.getState());
a.setCity(b.getCity());
a.setSales(a.getSales() + b.getSales());
return a;
} ))));
Убедитесь, что ваш год и месяц одинаковы для всех объектов, иначе он будет утерян (если вам не все равно).