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

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.


Here is a stream way of doing it (though my first instinct itself would be to follow Federico's solution) :

private static <T, K> Map<T, List<K>> invertedMapOfList(Map<K, List<T>> m) {
    return m.entrySet()
        .stream()
        .flatMap(e -> e.getValue()
            .stream()
            .map(v -> new AbstractMap.SimpleEntry<>(e.getKey(), v)))
        .collect(Collectors.groupingBy(Map.Entry::getValue,
            Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
}

Hope this will solve your problem.

private static <T, K> Map<T, List<K>> invertedMap(Map<K, List<T>> m) {
    Map<T, List<K>> result = new HashMap<T, List<K>>();

    for (K key : m.keySet()) {
        for (T value : m.get(key)) {
            List<K> kList = null;
            if ((kList = result.get(value)) == null) {
                kList = new ArrayList<K>();
            }
            kList.add(key);
            result.put(value, kList);
        }
    }
    return result;
}