Reverse Hashmap Keys and Values in Java

Reverse HashMap keys and values in Java

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 java-8 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();

How to reverse a HashMap?

Please check if the below code I've written is useful for you as a reference:

public void reverseMap()
{
NavigableMap<Integer,String> map = new TreeMap<Integer,String>();
LinkedHashMap<Integer,String> reverseMap = new LinkedHashMap<Integer,String>();
map.put(1,"Apple");
map.put(2,"Ball");
map.put(3,"Cat");
NavigableSet<Integer> keySet = map.navigableKeySet();
Iterator<Integer> iterator = keySet.descendingIterator();
Integer i;
while(iterator.hasNext())
{
i = iterator.next();
reverseMap.put(i,map.get(i));
}
System.out.println(reverseMap);
}

Invert Map | Values --- Keys

Do it like this. Basically, it employs a merge function which concatenates values for a duplicate key.

  • Create a new map
  • Use the values of the old map for the keys to the new
  • If the new map does not have a value for the key, put the value in the new map
  • Otherwise, concatenate the value to the old value for that key
        HashMap<String, String> cities = new HashMap<String, String>();

cities.put("Manchester", "UK");
cities.put("London", "UK");
cities.put("New York", "US");
cities.put("Chicago", "US");

Map<String,String> inverted = new HashMap<>();
for (String key : cities.keySet()) {
String newKey = cities.get(key);
String value = inverted.get(newKey);
if (value == null) {
inverted.put(newKey, key);
} else {
value = value + ", " + key;
inverted.put(newKey, value);
}

}
for (Entry<String,String> e : inverted.entrySet()) {
System.out.println(e.getKey() + " -> " + e.getValue());
}

It prints

UK -> Manchester, London
US -> New York, Chicago

Since you didn't specify how to handle duplicate keys. I could also have stored it in a Map<String,List<String>>

How to iterate hashmap in reverse order in Java

Hashmap does not have specific order. But you can use TreeMap.

Perhaps this simple example can help you :

Map<Integer, String> map = new TreeMap<Integer, String>();
map.put(1, "abc1");
map.put(2, "abc2");
map.put(3, "abc3");

ArrayList<Integer> keys = new ArrayList<Integer>(map.keySet());
for(int i=keys.size()-1; i>=0;i--){
System.out.println(map.get(keys.get(i)));
}

Reversing key value pairs in a HashMap

There's a bug in your code:

for (Map.Entry<String, ArrayList<String>> entry : adjList.entrySet()) {
String key = entry.getKey();
ArrayList<String> values = new ArrayList<>(); // Wrong place for this variable.
values.add(key);
ArrayList<String> value = entry.getValue();
for(String v:value){
if(tGraph.containsKey(v)){
values.addAll(tGraph.get(v));
}
tGraph.put(v, values);
}
}

The local variable values should be in the nested for loop, otherwise values are accumulated for all later new key v and will cost a lot of memory if your dataset is large, it should be:

private Map<String, ArrayList<String>> reverseAdjList(Map<String, List<String>> adjList) {
Map<String, ArrayList<String>> tGraph = new HashMap<>();
for (Map.Entry<String, List<String>> entry : adjList.entrySet()) {
String key = entry.getKey();
List<String> value = entry.getValue();
for (String v : value) {
ArrayList<String> values = new ArrayList<>();
values.add(key);
if (tGraph.containsKey(v)) {
values.addAll(tGraph.get(v));
}
tGraph.put(v, values);
}
}
return tGraph;
}

But actually you don't need to create a new List instance for each inner for step, try the following code with JDK 1.8:

private  Map<String, List<String>> reverseMap(Map<String, List<String>> adjList) {
Map<String, List<String>> tGraph = new HashMap<>();
for (Map.Entry<String, List<String>> entry : adjList.entrySet()) {
for (String value : entry.getValue()) {
tGraph.computeIfAbsent(value, v -> new ArrayList<>()).add(entry.getKey()); // Updated according comment from @shmosel
}
}
return tGraph;
}

If you're using older version of jdk, you can try:

    private Map<String, List<String>> reverseMap(Map<String, List<String>> adjList) {
Map<String, List<String>> tGraph = new HashMap<>();
for (Map.Entry<String, List<String>> entry : adjList.entrySet()) {
for (String value : entry.getValue()) {
List<String> newValues = tGraph.get(value);
if (newValues == null) {
newValues = new ArrayList<>();
tGraph.put(value, newValues);
}
newValues.add(entry.getKey());
}
}
return tGraph;
}

Hope this could be helpful :-)

Change LinkedHashMap items in reverse order

You can use this code to iterate in reverse order:

   ListIterator<Map.Entry<String, Integer>> iterator = new ArrayList<Map.Entry<String, Integer>>(map.entrySet()).listIterator(map.size());
while (iterator.hasPrevious()) {
Map.Entry<String, Integer> entry = iterator.previous();
System.out.println(entry.getValue());
}

reversing keys/values - create new instance of HashMap

do you mean you want some thing like Map, String> !!

Thn you can iterate over existing map and put reversed key values in a new map

Example:

Map<Set<String>, String> somemap = new HashMap<Set<String>, String>();
foreach(Map.entry entry : existingMap.entrySet()) {
Set<String> value = entry.getValue();
String key = entry.getKey();
somemap.put(value,key);

}

Reverse Map structure using Java 8 streams

I think you can do

Map<Integer, List<MyClass>> mapSectionIdToListOfMyClass = mapLangIdToListOfMyClass
.values()
.stream()
.flatMap(List::stream)
.collect(Collectors.groupingBy(j -> j.sectionId));

Java HashMap reverse way

You can use Guava BiMap :

BiMap<String, Long> map = HashBiMap.create();
map.put("a", 1L);
map.put("b", 2L);
map.put("c", 3L);

System.out.println(map.get("b")); // 2L
System.out.println(map.inverse().get(2L)); // "b"

An other alternative is Apache commons BidiMap :

BidiMap<String, Long> map = new DualHashBidiMap<>();
map.put("a", 1L);
map.put("b", 2L);
map.put("c", 3L);

System.out.println(map.get("b")); // 2L
System.out.println(map.inverseBidiMap().get(2L)); // "b"


Related Topics



Leave a reply



Submit