2

I have an object, "Item" with fields: int: id String: prices

The string prices contains one or more price values separated by comma.

Problem: Using stream operations I want a map of type Map<Integer,Set<Integer>> from List<Item> items

where key of Map is id and Set has value of prices as Integer extracted from the String prices.

There will be repeated ids in the List and can have different price strings.

I have come up with an approach which produces the following result:

Map<Integer, Set<List<Integer>>> itemStoresMapIntermediate = items.stream()
            .collect(Collectors.groupingBy(Item::getItemId,Collectors.mapping(Item::getStoresAsIntList, Collectors.toSet())));

getStoresAsIntList() returns List of price values from String prices in the object.

The above is certainly not what I want.

rohit
  • 96
  • 1
  • 6
  • Will one stream contain multiple items of the same ID? – Magnus Mar 07 '17 at 11:34
  • What does `getStoresAsIntList` do? – Holger Mar 07 '17 at 11:37
  • Yes, there will be multiple items of same id. – rohit Mar 07 '17 at 11:37
  • getStoresAsIntList returns List of price values in String prices – rohit Mar 07 '17 at 11:38
  • If the IDs are unique, you can use `Collectors.toMap(Item::getItemId, i->new HashSet<>( i.getStoresAsIntList()))`. Otherwise, you need to do either, `flatMap` to some kind of key-price pair before `groupingBy` or use a `flatMapping` collector like at the end of [this answer](http://stackoverflow.com/a/39131049/2711488). – Holger Mar 07 '17 at 11:48

1 Answers1

5

If I understood correctly...

 Item item1 = new Item(1, "22,23,24");
 Item item2 = new Item(2, "33,34,35");
 Item item3 = new Item(1, "22,57,58");

 Map<Integer, Set<Integer>> map = Stream.of(item1, item2, item3)
            .collect(Collectors.toMap(
                    Item::getId,
                    i -> new HashSet<>(i.getStoresAsIntList()),
                    (left, right) -> {
                        left.addAll(right);
                        return left;
                    }, HashMap::new));

 System.out.println(map); // {1=[22, 23, 24, 57, 58], 2=[33, 34, 35]}
Eugene
  • 117,005
  • 15
  • 201
  • 306