Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create Map<T, List<K>> out of Map<K, List<T> >?

I am trying to implement the function:

private static <T, K> Map<T, List<K> > invertedMap(Map<K, List<T> > m)

For example if I have Map<String, List<Integer> > ,

I want to create another Map<Integer, List<String> >.

I have written some code:

private static <T, K> Map<T, List<K>> invertedMap(Map<K, T> m) {
    return m.keySet().stream()
            .collect(Collectors.groupingBy(k -> m.get(k)));
}

but as you can see this only works if the map in the argument doesn't contain list as values.

like image 917
Makedon makedonski Avatar asked Feb 07 '19 16:02

Makedon makedonski


People also ask

Can we convert list to Map in Java?

With Java 8, you can convert a List to Map in one line using the stream() and Collectors. toMap() utility methods. The Collectors. toMap() method collects a stream as a Map and uses its arguments to decide what key/value to use.

Can the key of a Map be a list?

Yes you can have ArrayList s as a keys in a hash map, but it is a very bad idea since they are mutable.


1 Answers

I wouldn't use streams for this (if you want a stream-based solution, check nullpointer's answer):

private static <T, K> Map<T, List<K>> invertedMap(Map<K, List<T>> map) {
    Map<T, List<K>> result = new LinkedHashMap<>(); // Preserves insertion order 
    map.forEach((k, l) -> 
           l.forEach(t -> result.computeIfAbsent(t, d -> new ArrayList<>()).add(k)));
    return result;
}

The above code iterates the input map map and for each element t of each one of its List values l, it uses Map.computeIfAbsent to create the result.

Map.computeIfAbsent returns the value if there's an entry for the given key, or creates the entry and returns the value specified by its second argument d -> new ArrayList<>() (here d stands for a dummy argument that we don't need in order to create a new, empty list). Then, the key k is added to the list returned by Map.computeIfAbsent.

like image 58
fps Avatar answered Oct 20 '22 01:10

fps