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.
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.
Yes you can have ArrayList s as a keys in a hash map, but it is a very bad idea since they are mutable.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With