Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Reverse a Map (A – B List) to (B – A List)

I made up this function, it seems to make the work, but I wondered if there was an even cleaner solution.

    public static <K, V> Map<V, List<K>> reverseMap(Map<K, List<V>> map) {
        return map.entrySet().stream()
                .flatMap(entry -> entry.getValue().stream().map(value -> new AbstractMap.SimpleEntry<>(value, entry.getKey())))
                .collect(Collectors.groupingBy(
                        AbstractMap.SimpleEntry::getKey,
                        Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList())));

    }

Bonus question: I have a java 8 constraint for this one, but how could later versions improve it? I assume I’d no longer have to use AbstractMap.SimpleEntry since Java 9 introduced the Map.entry(k, v) function.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Since you did not necessitate streams in your question, I’m going to advocate for a non-stream solution:

//example input
Map<Integer, List<Integer>> map = new HashMap<>();
map.put(1, Arrays.asList(11, 12, 13, 4));
map.put(2, Arrays.asList(21, 22, 23, 4));
map.put(3, Arrays.asList(31, 32, 33, 4));
//reversing
Map<Integer, List<Integer>> reversed = new HashMap<>();
map.forEach((key, list) -> {
    list.forEach(value -> {
        reversed.computeIfAbsent(value, k -> new ArrayList<>()).add(key);
    });
});
//end result:
//{32=[3], 33=[3], 4=[1, 2, 3], 21=[2], 22=[2], 23=[2], 11=[1], 12=[1], 13=[1], 31=[3]}

In your stream-based solution, you will be creating new Entry objects per key-(list-value) pair in the map, which will then have to make additional entries when recombined into a map. By using a direct approach, you avoid this excess object creation and directly create the entries you need.

Note that not everything has to be a Stream, the "old" way of doing things can still be correct, if not better (in readability and performance terms) than a Stream implementation.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading