Reputation: 19
I am new to Java 8 Stream API. I am wondering if I can create multiple lists based on the Key Value from a Map? For Example. If my Map is
{"Developer", Developer; "Manager", Manager; "Lead", Lead; "Director", Director}
I would like to create a List of Developer, List of Manager, List of Lead and List of Director from the Map based on the Key Values.Any help is appreciated.
Upvotes: 0
Views: 1179
Reputation: 91
Please find below code for the same by using Collectors.groupBy() :
List<Details> employeeList = Arrays.asList(new Details("Pratik", "Developer"), new Details("Rohit", "Manager"), new Details("Sonal", "Developer"), new Details("Sagar", "Lead"), new Details("Sanket", "Lead"));
Map<String, List<Details>> collect = employeeList.stream().collect(Collectors.groupingBy(x-> x.getDesignation()));
System.out.println("Checking details "+ collect);
Upvotes: 0
Reputation: 269877
To invert a map, so that its distinct values become keys, and its keys are added to a collection under the corresponding value, use groupingBy()
on the map entries. It's important that the values from the original map implement equals()
and hashCode()
correctly to be used as a key in the new hash table .
static <K, V> Map<V, Set<K>> invert(Map<? extends K, ? extends V> original) {
return original.entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toSet())
));
}
If you want to groups to be sorted, you can create a specialized "downstream" collector:
static <K, V> Map<V, SortedSet<K>> invert(
Map<? extends K, ? extends V> original,
Comparator<? super K> order) {
Collector<K, ?, SortedSet<K>> toSortedSet =
Collectors.toCollection(() -> new TreeSet<>(order));
return original.entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, toSortedSet)
));
}
Upvotes: 0
Reputation: 2651
Using Collectors.groupingBy
, you can generate a Map from your Key to a List of Values, provided you can compute the Key from the Value. Alternatively, you can use Collectors.toMap
, provided you can compute both the Key and the Value from an upstream element. You probably want the version of toMap with a merge function, because that will allow you to handle multiple keys with the same value (by putting them in a list together).
Edit:
If you want ordering, there are overloads for toMap and groupingBy that allow you to provide a mapFactory (Supplier<Map>
) , such as TreeMap::new
.
Upvotes: 2