Redskin Fan
Redskin Fan

Reputation: 19

How do I create multiple lists from java Map using Stream?

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

Answers (3)

Pratik Pawar
Pratik Pawar

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

erickson
erickson

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

Avi
Avi

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

Related Questions