-2

Having an instance of a Map<A, Set<B>> where B is a POJO with property Integer price (among others), how do I elegantly transform this map into a Map<A, Integer> where Integer denotes the sum of prices of a given set, for each key A?

weno
  • 804
  • 8
  • 17
  • @Michael That's not very helpful comment. I know how to solve it with explicit loop, I'm not sure about streams. – weno Jan 11 '21 at 13:14
  • 1
    @weno then show your attempt with loops. That way it is quite easy to create a stream solution – Lino Jan 11 '21 at 13:15

2 Answers2

2

You can use stream like this:

Map<A, Integer> result = map.entrySet().stream()
        .collect(Collectors.toMap(
                Map.Entry::getKey, 
                b -> b.getValue().stream()
                        .mapToInt(B::getPrice)
                        .sum()
                ));
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
-2

That should help you out. Using the Streaming-API from Java 8: (In this example the class "PricePojo" is your B and "String" is your A)

 Map<String, Integer> newMap = map.entrySet().stream()//
.collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().stream().mapToInt(PricePojo::getPrice).sum()));

You could also go the way of implementing a Map.Entry yourself like in the following example:

    Map<String, Integer> newMap = map.entrySet().stream()//
    .map(entry -> new Map.Entry<String, Integer>() {
    private int sum = entry.getValue().stream().mapToInt(PricePojo::getPrice).sum();
    @Override
    public String getKey() {
        return entry.getKey();
    }

    @Override
    public Integer getValue() {
        return sum;
    }

    @Override
    public Integer setValue(Integer value) {
        return sum = value.intValue();
    }
    }).collect(Collectors.toMap(Entry::getKey, Entry::getValue));