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?
  • Вопрос задан
  • 360 просмотров
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Java
Седой и строгий
Автор вопроса потерялся, придётся предлагать возможные варианты. Начну с самого простого - группировки в 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())));
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
EreminD
@EreminD
Кое-что умею
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽