Вы можете использовать groupByEach
из Eclipse Collections .
Multimap<String, Item> itemsByCategory =
ListIterate.groupByEach(myItemList, Item::getBelongsToCategories);
System.out.println(itemsByCategory);
Вывод:
{D=[Item{id=4}, Item{id=5}],
E=[Item{id=5}],
F=[Item{id=6}],
A=[Item{id=1}, Item{id=2}, Item{id=6}],
B=[Item{id=1}, Item{id=3}],
C=[Item{id=2}, Item{id=3}]}
Вы также можете использовать служебный класс Collectors2
и groupByEach
Collector с Java Stream
.
Multimap<String, Item> itemsByCategory = myItemList.stream().collect(
Collectors2.groupByEach(
Item::getBelongsToCategories,
Multimaps.mutable.list::empty));
Примечание: я являюсь коммиттером для Eclipse Collections.
Вот решение от ListMultimap
, либо из Google Guava или моей библиотеки Abacus-Util
ListMultimap<String, Item> result = Multimaps.newListMultimap(new HashMap<>(), () -> new ArrayList<>()); // by Google Guava.
// Or result = N.newListMultimap(); // By Abacus-Util
items.forEach(item -> item.getBelongsToCategories().forEach(c -> result.put(c, item)));
Я думаю, что это будет немного более эффективный и лаконичный без создания ненужных временных Entry
объектов по flatMap
.
Вы можете использовать flatMap
для отображения на SimpleEntry
, а затем groupingBy
как:
return items.stream()
.flatMap(p -> p.getBelongsToCategories()
.stream()
.map(l -> new AbstractMap.SimpleEntry<>(l, p)))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue,
Collectors.toList())));