2015-10-29 2 views
3

Я пытаюсь сделать groupingBy по двум атрибутам объекта с потоками Java. Это достаточно просто, как было документально подтверждено некоторыми ответами:Java 8- Несколько групп по карте Map

products.stream().collect(
     Collectors.groupingBy(Product::getUpc, 
     Collectors.groupingBy(Product::getChannelIdentifier))); 

, например, выше фрагмент кода будет производить Карту Карты в виде

Map<String, Map<String, List<Product>>> 

Если карта имеет ключи UPC кодов и его значения - это карты с ключами идентификаторов каналов, которые ссылаются на список продуктов.

Это круто, но что, если мне не нужно, чтобы вложенное значение представляло собой карту? То есть, я хочу организовать вложенную коллекцию с помощью ChannelIdentifier, но мне только заботится о .values ​​() карты, а не о самой карте. Есть ли способ получить результат, который соответствует следующему?

Map<String, List<List<Product>> 

Списки или коллекции ... это не имеет значения. Благодаря!

ответ

8

Операция группировки неизбежно должна поддерживать Map, поскольку она должна отслеживать значения ключей для группировки. Но вы можете использовать values() вид непосредственно:

Map<String, Collection<List<Product>>> m=products.stream().collect(
    Collectors.groupingBy(Product::getUpc, Collectors.collectingAndThen(
     Collectors.groupingBy(Product::getChannelIdentifier), Map::values))); 

Если полученная карта будет иметь более длительный срок службы, и вы хотите, чтобы уменьшить требуемый объем памяти, или если вам нужен List, вы можете скопировать вид в список во время этого шага:

Map<String, List<List<Product>>> map=products.stream().collect(
    Collectors.groupingBy(Product::getUpc, Collectors.collectingAndThen(
     Collectors.groupingBy(Product::getChannelIdentifier), 
     m -> new ArrayList<>(m.values())))); 
+0

Marvelous- спасибо! Из любопытства, как вы узнали о «collectAndThen»? Вы запомнили документы API или у вас есть хороший ресурс для этого? – IcedDante

+4

Я запоминаю [API] (http://docs.oracle.com/javase/8/docs/api/?java/util/stream/Collectors.html), отвечая на вопросы SO и читая другие [связанные ответы] (http : //stackoverflow.com/search д =% 5Bjava-8% 5D + коллекторы + является% 3Aanswer). Обучение - хороший побочный эффект. – Holger

+0

только что сэкономили на день. – SparkOn

Смежные вопросы