Reverse HashMap keys and values in Java

131,858

Solution 1

They all are unique, yes

If you're sure that your values are unique you can iterate over the entries of your old map .

Map<String, Character> myNewHashMap = new HashMap<>();
for(Map.Entry<Character, String> entry : myHashMap.entrySet()){
    myNewHashMap.put(entry.getValue(), entry.getKey());
}

Alternatively, you can use a Bi-Directional map like Guava provides and use the inverse() method :

BiMap<Character, String> myBiMap = HashBiMap.create();
myBiMap.put('a', "test one");
myBiMap.put('b', "test two");

BiMap<String, Character> myBiMapInversed = myBiMap.inverse();

As is out, you can also do it this way :

Map<String, Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);

Map<Integer, String> mapInversed = 
    map.entrySet()
       .stream()
       .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey))

Finally, I added my contribution to the proton pack library, which contains utility methods for the Stream API. With that you could do it like this:

Map<Character, String> mapInversed = MapStream.of(map).inverseMapping().collect();

Solution 2

Apache commons collections library provides a utility method for inversing the map. You can use this if you are sure that the values of myHashMap are unique

org.apache.commons.collections.MapUtils.invertMap(java.util.Map map)

Sample code

HashMap<String, Character> reversedHashMap = MapUtils.invertMap(myHashMap) 

Solution 3

If the values are not unique, the safe way to inverse the map is by using java 8's groupingBy function

Map<String, Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);

Map<Integer, List<String>> mapInversed = 
map.entrySet()
   .stream()
   .collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())))

Solution 4

I wrote a simpler loop that works too (note that all my values are unique):

HashMap<Character, String> myHashMap = new HashMap<Character, String>();
HashMap<String, Character> reversedHashMap = new HashMap<String, Character>();

for (char i : myHashMap.keySet()) {
    reversedHashMap.put(myHashMap.get(i), i);
}

Solution 5

To answer your question on how you can do it, you could get the entrySet from your map and then just put into the new map by using getValue as key and getKey as value.

But remember that keys in a Map are unique, which means if you have one value with two different key in your original map, only the second key (in iteration order) will be kep as value in the new map.

Share:
131,858

Related videos on Youtube

Ken
Author by

Ken

Updated on November 11, 2021

Comments

  • Ken
    Ken over 2 years

    It's a simple question, I have a simple HashMap of which i want to reverse the keys and values.

    HashMap<Character, String> myHashMap = new HashMap<Character, String>();
    myHashMap.put('a', "test one");
    myHashMap.put('b', "test two");
    

    and I want to create a new HashMap in which i put the opposites.

    HashMap<String, Character> reversedHashMap = new HashMap<String, Character>();
    e.g. Keys "test one" & "test two" and values 'a' & 'b'.
    
    • Jeroen Vannevel
      Jeroen Vannevel over 10 years
      Simple question, simple answer. Can you tell us where you got stuck?
    • Alexis C.
      Alexis C. over 10 years
      First of all you have to be sure that your values are unique. Otherwise, it should be Map<String, List<Character>>
    • Ken
      Ken over 10 years
      well, I'm fairly new to JAVA and wouldn't know where to start... They all are unique, yes
    • peter.petrov
      peter.petrov over 10 years
      This is not always possible to do without losing data. Imagine you have this: a -> test one; b -> test two; c -> test one (in your first map). What will you get in your second (output) map? Something like this: test one -> a (or c); test two -> b. So 1st map has 3 entries, 2nd map has just 2.
  • A4L
    A4L over 10 years
    entrySet is better, the hash code has not to be computed on each get
  • hichris123
    hichris123 over 10 years
    @A4L That's true, but for simple tasks there's not much of a difference.
  • Erçin Akçay
    Erçin Akçay almost 10 years
    Thanks for explanation of Bi-Directional map usage. I didn't know that and it is really useful for me!
  • Jan
    Jan about 7 years
    When I use your java-8 method with the collectors, I get the following error on Map.Entry::getValue and getKey: Non-static method cannot be referenced from a static context
  • Marcin
    Marcin about 7 years
    Jan, it's because your map is of a different generic type than declared with the the mapInversed variable.
  • Chaitanya Uttarwar
    Chaitanya Uttarwar over 6 years
    what if values are duplicate ? how do you handle that ?
  • Alexis C.
    Alexis C. over 6 years
    @ChaitanyaUttarwar You'd have to find a merging strategy to map the different keys that are associated with the same value in your original map (you could group them into a list, sum them, take only one key depending on what you want to achieve).
  • Cooper Buckingham
    Cooper Buckingham about 6 years
    I think a note about how duplicate values becoming keys will be handled would be useful.
  • Mark Hetherington
    Mark Hetherington about 6 years
    @CHBuckingham agreed