Java 8 Stream groupingby
У меня есть List<Map<String, String>>
каждый элемент в списке - это карта, например,
companyName - IBM
firstName - James
country - USA
...
Я хотел бы создать Map<String, List<String>>
, где он сопоставляет имя_компании с списком firstName
например,
IBM -> James, Mark
ATT -> Henry, Robert..
private Map<String,List<String>> groupByCompanyName(List<Map<String, String>> list) {
return list.stream().collect(Collectors.groupingBy(item->item.get("companyName")));
}
но это создаст Map<String, List<Map<String, String>>
(сопоставление comanyName со списком карт)
как создать Map<String, List<String>>
?
Ответы
Ответ 1
Не тестировали, но что-то вроде этого должно работать:
Map<String, List<String>> namesByCompany
= list.stream()
.collect(Collectors.groupingBy(item->item.get("companyName"),
Collectors.mapping(item->item.get("firstName"), Collectors.toList())));
Ответ 2
Вы можете использовать форму:
groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)
то есть. укажите значения из карты в списке ниже по течению, которые нужно взять в качестве списка. В документации есть хороший пример (здесь).
downstream
будет что-то вроде - mapping(item->item.get(<name>), toList())
Ответ 3
Метод groupingBy дает карту, значения которой являются списками. Если вы хотите каким-то образом обработать эти списки, поставьте "нисходящий коллекционер",
В этом случае вы не хотите, чтобы в качестве значения использовался List, поэтому вам необходимо предоставить нисходящий коллекционер.
Чтобы манипулировать Картой, вы можете использовать сопоставление статических методов в файле Collectors:
Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
Collector<? super U, A, R> downstream)
Он в основном генерирует коллектор, применяя функцию к результатам нисходящего потока и передает функцию другому коллектору.
Collectors.mapping(item->item.get("firstName"), Collectors.toList())
Это вернет сборщик нисходящего потока, который достигнет того, что вы хотите.