Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overwriting values in a HashMap that are in an ArrayList<String>

Let's say I have a HashMap with String keys and Integer values:

map = {cat=1, kid=3, girl=3, adult=2, human=5, dog=2, boy=2}

I want to switch the keys and values by putting this information into another HashMap. I know that a HashMap cannot have duplicate keys, so I tried to put the information into a HashMap with the Integer for the keys that would map to a String ArrayList so that I could potentially have one Integer mapping to multiple Strings:

swap = {1=[cat], 2=[adult, dog, boy], 3=[kid, girl], 5=[human]}

I tried the following code:

HashMap<Integer, ArrayList<String>> swap = new HashMap<Integer, ArrayList<String>>();

for (String x : map.keySet()) {
        for (int i = 0; i <= 5; i++) {
            ArrayList<String> list = new ArrayList<String>();
            if (i == map.get(x)) {
                list.add(x);
                swap.put(i, list);
            }
        }
    }

The only difference in my code is that I didn't hard code the number 5 into my index; I have a method that finds the highest integer value in the original HashMap and used that. I know it works correctly because I get the same output even if I hard code the 5 in there, I just didn't include it to save space.

My goal here is to be able to do this 'reversal' with any set of data, otherwise I could just hard code the value. The output I get from the above code is this:

swap = {1=[cat], 2=[boy], 3=[girl], 5=[human]}

As you can see, my problem is that the value ArrayList is only keeping the last String that was put into it, instead of collecting all of them. How can I make the ArrayList store each String, rather than just the last String?

like image 360
jtrain17 Avatar asked Jul 10 '17 14:07

jtrain17


2 Answers

With Java 8, you can do the following:

Map<String, Integer> map = new HashMap<>();

map.put("cat", 1);
map.put("kid", 3);
map.put("girl", 3);
map.put("adult", 2);
map.put("human", 5);
map.put("dog", 2);
map.put("boy", 2);

Map<Integer, List<String>> newMap = map.keySet()
                                       .stream()
                                       .collect(Collectors.groupingBy(map::get));

System.out.println(newMap);

The output will be:

{1=[cat], 2=[adult, dog, boy], 3=[kid, girl], 5=[human]}

like image 86
Jacob G. Avatar answered Oct 15 '22 17:10

Jacob G.


you are recreating the arrayList for every iteration and i can't figure out a way to do it with that logic, here is a good way though and without the need to check for the max integer:

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    List<String> get = swap.get(value);
    if (get == null) {
        get = new ArrayList<>();
        swap.put(value, get);
    }
    get.add(key);
}
like image 25
Zeromus Avatar answered Oct 15 '22 16:10

Zeromus