0

I have a HashMap<Integer, List<String>> as input, e.g :

3  :  a, b, c
6  :  b, c
9  :  a, c
12 :  b ,c

I want to convert it to HashMap<String, HashSet<Integer>> for e.g.

a : 3, 9
b : 3, 6, 12
c : 3, 6, 9, 12

How can it be done ?

4
  • Similar tasks have been covered on Stack Overflow before, with good answers, but they are hard to search for (I didn’t find an example readily). I still encourage you to try your search skills and luck. Commented May 30, 2017 at 13:41
  • 1
    Possible duplicate of Java8 streams : Transpose map with values as list Commented May 30, 2017 at 13:43
  • @OleV.V. Thanks for the link. This answer did help me reaching the final solution but still required some tweak. Map Response value is a HashSet instead of List. I think it can help a beginner like me. Please Let me know if you disagree. Commented May 30, 2017 at 20:22
  • I noticed that you answered your own question. I was happy about that and hurried to upvote your answer. I believe it deserves to be here. Very glad that my link helped. Commented May 30, 2017 at 20:25

4 Answers 4

2

This should help

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

initMap.put(3, new ArrayList<String>(Arrays.asList("a", "b", "c")));
initMap.put(6, new ArrayList<String>(Arrays.asList("b", "c")));
initMap.put(9, new ArrayList<String>(Arrays.asList("a", "c")));
initMap.put(12, new ArrayList<String>(Arrays.asList("b", "c")));

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

initMap.forEach((key, values) -> {
  values.forEach(val -> {
    Object o = finalMap.containsKey(val) ? 
             finalMap.get(val).add(key) : 
             finalMap.put(val, new HashSet<Integer>(Arrays.asList(key)));
  });
});
Sign up to request clarification or add additional context in comments.

Comments

1

Here's an example, along with tests:

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import org.junit.Assert;
import org.junit.Test;

public class SoTests {
    @Test
    public void so01() {
        HashMap<Integer, List<String>> input = new HashMap<>(4);
        input.put(3, Arrays.asList("a", "b", "c"));
        input.put(6, Arrays.asList("b", "c"));
        input.put(9, Arrays.asList("a", "c"));
        input.put(12, Arrays.asList("b", "c"));

        HashMap<String, HashSet<Integer>> output = process(input);

        HashMap<String, HashSet<Integer>> expectedOutput = new HashMap<>(3);
        expectedOutput.put("a", new HashSet<>(Arrays.asList(3, 9)));
        expectedOutput.put("b", new HashSet<>(Arrays.asList(3, 6, 12)));
        expectedOutput.put("c", new HashSet<>(Arrays.asList(3, 6, 9, 12)));
        Assert.assertEquals(expectedOutput, output);
    }

    private HashMap<String, HashSet<Integer>> process(HashMap<Integer, List<String>> input) {
        return input.entrySet().stream() //
            .flatMap(entry -> entry.getValue().stream().map(s -> new IntegerAndString(entry.getKey(), s))) //
            .collect(Collectors.groupingBy(IntegerAndString::getString, HashMap::new, //
                Collectors.mapping(IntegerAndString::getInteger, Collectors.toCollection(HashSet::new))));
    }

    private static class IntegerAndString {
        private final Integer integer;
        private final String string;

        IntegerAndString(Integer integer, String string) {
            this.integer = integer;
            this.string = string;
        }

        Integer getInteger() {
            return integer;
        }

        String getString() {
            return string;
        }
    }
}

The actual logic is in the process method. The ugly IntegerAndString class is due to a lack of tuple types in Java. You can use some library like javatuples instead.

1 Comment

thanks for the code snippet. Can you add some explanation to it. ? (The streaming part)
1

Just looking at Duplicate link.

This is the final solution I have

 private HashMap<String, HashSet<Integer>> process(HashMap<Integer, List<String>> input) {
     return input.entrySet().stream()
             .flatMap(entry -> entry.getValue().stream().map(s -> new SimpleEntry<>(entry.getKey(), s)))
             .collect(Collectors.groupingBy(SimpleEntry::getValue, HashMap::new,
                 Collectors.mapping(SimpleEntry::getKey, Collectors.toCollection(HashSet::new))));
     }

1 Comment

This is a fine tweak of the answer from the linked question to fit your particular requirements (the requirement to have sets as values in the result map in particular).
0
Map<Integer, List<String>> intHM = new HashMap<Integer, List<String>>();

    intHM.put(3, new ArrayList<String>(Arrays.asList("a","b","c")));

    intHM.put(6, new ArrayList<String>(Arrays.asList("b","c")));

    intHM.put(9, new ArrayList<String>(Arrays.asList("a","c")));

    intHM.put(12, new ArrayList<String>(Arrays.asList("b","c")));

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

    Iterator<Entry<Integer,List<String>>> iterator = intHM.entrySet().iterator();

    while (iterator.hasNext()) {

        Map.Entry<Integer,List<String>> entry = (Map.Entry<Integer,List<String>>) iterator.next();

        for(String str: entry.getValue())
        {

            if (StringHM.containsKey(str))
                StringHM.get(str).add(entry.getKey());
            else
                StringHM.put(str, new ArrayList<Integer>(Arrays.asList(entry.getKey())));

        }
    }

    Iterator<Entry<String,List<Integer>>> StringIterator = StringHM.entrySet().iterator();

    while (StringIterator.hasNext()) {

        Map.Entry<String,List<Integer>> entry = (Map.Entry<String,List<Integer>>) StringIterator.next();

        System.out.print(entry.getKey()+" ");

        for(Integer i: entry.getValue())

            System.out.print(i+" ");

        System.out.println();
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.