Java 8 stream: sum of units of the same element

Is there a condensed way to sum units of the same type of items in a list with Java 8 threads? For example, suppose I have a list of three elements:

{id: 10, units: 1}
{id: 20, units: 2}
{id: 10, units: 1}

I like the summary stream like:

{id: 10, units 2}
{id: 20, units 2}

which sums up the units of elements of the same identifier. Any ideas?


Here's the Federico solution (with Lombok):

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


public class So44348207 {

    public static void main(String[] args) {
        List<Item> items = Arrays.asList(
            new Item(10,1), new Item(20,2), new Item(10, 1)
        );

        Map<Long, Integer> results = items.stream().collect(
            Collectors.toMap(
                Item::getId,
                Item::getUnits,
                Integer::sum
                )
            );

        results.forEach( (k,v) -> System.out.println(
            String.format("{id: %d, units: %d}", k,v))
        );
    }

    @Data
    @AllArgsContructor
    public static class Item {
        Long id;
        Integer units;
    }
}

which correctly produces:

java So44348207 
{id: 20, units: 2}
{id: 10, units: 2}
+4
source share
2 answers

Assuming you have a class MyClassthat encapsulates both fields and has getters for them, you can do this as follows:

Map<Long, Integer> result = list.stream()
    .collect(Collectors.toMap(
        MyClass::getId,
        MyClass::getUnits,
        Integer::sum));

, id long long units int Integer.

Collectors.toMap , , , . - , , - , .

+5

StreamEx

StreamEx.of(items).toMap(Item::getId, Item::getUnits, Integer::sum);
+1

Source: https://habr.com/ru/post/1678475/


All Articles