5

I have created a Map using a String as a key and Integer as a value. So, it is like citiesWithCodes.

I have put the values in Hashmap manually as of now, for the testing purpose. They are:

Map<String, Integer> citiesWithCodes = new HashMap<String, Integer>();
        citiesWithCodes.put("Berlin", 49);
        citiesWithCodes.put("Frankfurt", 49);
        citiesWithCodes.put("Hamburg", 49);
        citiesWithCodes.put("Cologne", 49);
        citiesWithCodes.put("Salzburg", 43);
        citiesWithCodes.put("Vienna", 43);
        citiesWithCodes.put("Zurich", 41);
        citiesWithCodes.put("Bern", 41);
        citiesWithCodes.put("Interlaken", 41);

I want to fetch the cities in a List or an Array format according to their codes. So, for example for a value 43, it should return something like {43=[Vienna, Salzburg]}.

I have tried the following approach. It is a definitely dirty approach and isn't giving the correct reults.

   public static Map<Integer, List<String>> codeCities(Map<String, Integer> citiesWithCodes){
       Map<Integer, List<String>> segList = new HashMap<Integer, List<String>>();
       List<String> city;
       Iterator<Entry<String, Integer>> i = citiesWithCodes.entrySet().iterator();
       while (i.hasNext()) {
           city = new ArrayList<String>();
           Entry<String, Integer> next = i.next();
           i.remove();
           city.add(next.getKey());
           for (Entry<String, Integer> e : citiesWithCodes.entrySet()) {
               if(e.getValue().equals(next.getValue())){
                   city.add(e.getKey());
                   citiesWithCodes.remove(e);
               }
           }
           System.out.println(city);
           segList.put(next.getValue(), city);
       }
       return segList;
   }

The output I am getting is: {49=[Cologne], 41=[Interlaken], 43=[Salzburg]} Could someone tell me, the correct approach to achieve the results?

PS: I know it is possible using MultiMap. But we are limited only to use Java Collection Framework and not Java 8 as well.

2
  • Can you use Java 8 for this ? Commented Sep 14, 2017 at 12:39
  • @SchiduLuca. Unfortunately the project scope is limited to Java 7. Commented Sep 14, 2017 at 12:42

3 Answers 3

10

Before java 8

package com.stackoverflow;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class HashMapToListMap {

public static void main(String[] args) {
    Map<String, Integer> citiesWithCodes = new HashMap<String, Integer>();
    citiesWithCodes.put("Berlin", 49);
    citiesWithCodes.put("Frankfurt", 49);
    citiesWithCodes.put("Hamburg", 49);
    citiesWithCodes.put("Cologne", 49);
    citiesWithCodes.put("Salzburg", 43);
    citiesWithCodes.put("Vienna", 43);
    citiesWithCodes.put("Zurich", 41);
    citiesWithCodes.put("Bern", 41);
    citiesWithCodes.put("Interlaken", 41);
    
    Map<Integer, List<String>> result = new HashMap<Integer, List<String>>();
    for(Entry<String,Integer> entry : citiesWithCodes.entrySet()){
            List<String> list = new ArrayList<String>();
            if(result.containsKey(entry.getValue()))
                list = result.get(entry.getValue());
            list.add(entry.getKey());
            result.put(entry.getValue(), list);
    }
    System.out.println(result);
}

}

After java 8

 package com.stackoverflow;

 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;

public class HashMapToListMap {

public static void main(String[] args) {
    Map<String, Integer> citiesWithCodes = new HashMap<String, Integer>();
    citiesWithCodes.put("Berlin", 49);
    citiesWithCodes.put("Frankfurt", 49);
    citiesWithCodes.put("Hamburg", 49);
    citiesWithCodes.put("Cologne", 49);
    citiesWithCodes.put("Salzburg", 43);
    citiesWithCodes.put("Vienna", 43);
    citiesWithCodes.put("Zurich", 41);
    citiesWithCodes.put("Bern", 41);
    citiesWithCodes.put("Interlaken", 41);
    
    
    Map<Integer, List<String>> result =  citiesWithCodes.entrySet().stream().collect(Collectors.groupingBy(
            Map.Entry::getValue,Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
    System.out.println(result);
}

}
Sign up to request clarification or add additional context in comments.

Comments

4

If your scope is limited to Java 7 then try changing as below code :

 Map<Integer, List<String>> segList = new HashMap<Integer, List<String>>();
 Iterator<Entry<String, Integer>> i = citiesWithCodes.entrySet().iterator();
            while (i.hasNext()) {
                  Entry<String, Integer> next = i.next();
                  if (segList.get(next.getValue()) != null) {
                       List<String> city= segList.get(next.getValue());
                       city.add(next.getKey());
                       segList.put(next.getValue(), city);
                  }else{
                        List<String> city=new ArrayList<String>();
                        city.add(next.getKey());
                        segList.put(next.getValue(), city);

                  }
            }

Output:

{49=[Frankfurt, Berlin, Hamburg, Cologne], 41=[Bern, Zurich, Interlaken], 43=[Vienna, Salzburg]}

Comments

0

You always construct a new List<String> to hold the list of cities with a given key. The happens in line

city = new ArrayList<String>();

Replace this by

if(segList.containsKey(next.getValue())) {
    city = segList.get(next.getValue());
} else {
    city = new ArrayList<String>();
}

and the code should work as expected.

Edit: @eran was faster but I leave it as it explains the error made in the less elegant and modern approach.

2 Comments

I need to add the values to city even before the for loop. So, I can't initiate that just in else part.
At this point there is no difference to the original code. Just replace your one line by my 5.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.