Использование сборщиков Java 8 Streams для увеличения значения на основе существующей пары ключ / значение - PullRequest
5 голосов
/ 14 июня 2019

Предположим, что есть List<Object> и что Object содержит два метода: getUserId и getPoints.

Учтите, что List<Object> содержит три объекта, и они содержат следующие данные:

userId A; 3 points
userId A; 5 points
userId B; 1 point

После правильного сбора я ожидаю, что Map<String, Integer> будет выглядеть так:

A: 8,
B: 1

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

this.service.getListObject()
    .stream()
    .collect(Collectors.toMap(Object::getUserId, Object::getPoints));

Однако этого оказалось недостаточно, поскольку он всегда заменяет ключ на самое новое значение, в результате чего получается:

A: 5,
B: 1

Как я могу настроить последние биты из Collectors.toMap(), чтобы автоматически увеличивать его значение в соответствии со значением, уже сохраненным на карте, чтобы я мог получить результат выше?

Ответы [ 2 ]

6 голосов
/ 14 июня 2019

Используйте Collectors.groupingBy вместе с Collectors.summingInt в качестве выходного коллектора:

this.service.getListObject()
    .stream().collect(Collectors.groupingBy(
        Object::getUserId, Collectors.summingInt(Object::getPoints)));
4 голосов
/ 14 июня 2019

Чтобы исправить начатую реализацию, вам нужна функция слияния:

...stream().collect(Collectors.toMap(CustomObject::getUserId, 
                    CustomObject::getPoints, Integer::sum)); // <--- summing value here

, который в конечном итоге также может быть представлен комбинацией groupingBy и summingInt.

...