-2

I have a Map(map1) whose key is another map(map2) and value is string.

The value of map1 has several duplicate, so I must group them and set as key in another map3 whose value has to be map2.

eg:

map1 {  [[a,b],xyz],  [[c,d],wrt] , [[e,f],xyz] , [[r,m],xyz]  }


output should be :

map3 {  [ xyz,[ [a,b],[e,f],[r,m] ] ]  , [ wrt,[ [c,d] ]

can i obtain like this ?

Thamodharan
  • 85
  • 1
  • 1
  • 7

4 Answers4

0

try MultiValueMap from (commons-collections) library

Map map1 = new HashMap<String[], String>();
map1.put(new String[]{"a", "b"}, "xyz");
map1.put(new String[]{"c", "d"}, "wrt");
map1.put(new String[]{"e", "f"}, "xyz");
map1.put(new String[]{"c", "d"}, "xyz");

MultiValueMap map2 = new MultiValueMap();
for(String[] key: map1.keySet()) {
    String value = map1.get(key);
    map2.add(value, key);
}
// now you got map2 as you want
treesong
  • 193
  • 7
0

NO, Though you can declare it but while using it, it may allow same keys(human readable). Because Map do not override Object's equals method your key comparison will be on JVM's object level (it may be different for objects with same values in them).

S Jayesh
  • 191
  • 1
  • 4
  • 19
  • `Map` is an interface so why should it overwrite `equals`. BTW: `AbstractMap` overwrites `equals` and most (or all?) implementations of `java.util` extending this class. – Stefan Warminski May 09 '17 at 10:13
  • here `Map` is ( I thought obvious ) a solid implementation of `Map` interface. And you will not create another implementation of `Map` so you will not be able to edit the previous JAVA provided implementations for overriding `equals`. This is the reason answer is **NO** – S Jayesh May 09 '17 at 10:26
0

You can use the stream API to solve it:

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

Explanation: The entries will be grouped by its values (groupingBy(Entry::getValue). But the values should not be a list of entries so the downstream is necessary. This is the list of keys of the original map.

Stefan Warminski
  • 1,845
  • 1
  • 9
  • 18
0

It is not clear from your post what do you mean by map2, but let's assume you would like to use each Map.Entry<String, String> entry from map2 for each key for map1.

The following code is Java 7, it's a bit verbose. It could be done shorter with Java 8 streams, I guess.

public class MapReverser {

    private Map<Map.Entry<String, String>, String> map1 = new HashMap<>();

    private Map<String, String> map2 = new LinkedHashMap<>();

    private void prepareMaps() {
        map2.put("a", "b");
        map2.put("c", "d");
        map2.put("e", "f");
        map2.put("r", "m");

        String[] valueArray = { "xyz", "wrt", "xyz", "xyz" };
        int i = 0;
        for (Map.Entry<String, String> entry : map2.entrySet()) {
            map1.put(entry, valueArray[i]);
            i++;
        }
    }

    public Map<String, List<Map.Entry<String, String>>> reverse() {
        Map<String, List<Map.Entry<String, String>>> reversedMap = new HashMap<>();
        for (Map.Entry<Map.Entry<String, String>, String> entry : map1.entrySet()) {
            List<Map.Entry<String, String>> reversedMapValue = reversedMap.get(entry.getValue());
            if (reversedMapValue == null) {
                reversedMapValue = new ArrayList<>();
            }
            reversedMapValue.add(entry.getKey());
            reversedMap.put(entry.getValue(), reversedMapValue);
        }
        return reversedMap;
    }

    private void printResult(Map<String, List<Map.Entry<String, String>>> reversedMap) {
        for (Map.Entry<String, List<Map.Entry<String, String>>> entry : reversedMap.entrySet()) {
            System.out.println("Key: \n" + entry.getKey());
            System.out.println("Values:");
            List<Map.Entry<String, String>> valuesList = entry.getValue();
            for (Map.Entry<String, String> value : valuesList) {
                System.out.println(value );
            }
            System.out.println("\n");
        }
    }

    public static void main(String[] args) {
        MapReverser mapReverser = new MapReverser();
        mapReverser.prepareMaps();
        Map<String, List<Map.Entry<String, String>>> reversedMap = mapReverser.reverse();
        mapReverser.printResult(reversedMap);
    }
}
Vasiliy Vlasov
  • 3,316
  • 3
  • 17
  • 20