mitaichik
@mitaichik

Java Stream: можно ли сделать аггрегацию объектов?

Есть список объектов объектов:
{type : CAT, count : 1},
{type : CAT, count : 2},
{type : DOG, count : 5},


Нужно получить агрегированные данные, то есть собрать все объекты с одинаковым type в один, а поле count суммировать. То есть на выходе должно быть

{type : CAT, count : 3},       // 1 + 2
{type : DOG, count : 5},


Можно ли сделать это спомощью Stream API?
  • Вопрос задан
  • 74 просмотра
Пригласить эксперта
Ответы на вопрос 2
TheDeadOne
@TheDeadOne
Седой и строгий
Автор вопроса потерялся, придётся предлагать возможные варианты. Начну с самого простого - группировки в Map соответствующим коллектором:
Map<String, Integer> map = list.stream()
                                .collect(Collectors.toMap(Animal::getType,
                                                          Animal::getCount,
                                                          (a, b) -> a + b));

Чуть более сложный, хоть и проще выглядящий, но существенно более гибкий вариант - группирующий коллектор:
Map<String, Integer> map = list.stream()
                               .collect(Collectors.groupingBy(Animal::getType, 
                                                              Collectors.summingInt(Animal::getCount)));

Ну и совсем низкоуровневый вариант - написание собственного коллектора:
List<Animal> aggregated 
  = list.stream()
        .collect(Collector.of(HashMap<String, Integer>::new,
                              (acc, val) -> acc.compute(val.getType(), (k, v) -> v == null ? val.getCount() : v + val.getCount()),
                              (l, r) -> {
                                  l.replaceAll((k, v) -> v + r.getOrDefault(k, 0));
                                  return l;
                              },
                              acc -> acc.entrySet()
                                        .stream()
                                        .map(e -> new Animal(e.getKey(), e.getValue()))
                                        .collect(Collectors.toList())));
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы
ИП Шпак Виктория Сергеевна Санкт-Петербург
от 90 000 до 150 000 руб.
Payneteasy Москва
от 120 000 руб.
3В Сервис Москва
от 140 000 руб.
14 авг. 2018, в 16:33
1000 руб./за проект
14 авг. 2018, в 16:15
6000 руб./за проект
14 авг. 2018, в 16:12
500 руб./за проект