0

Let´s said that I have a Map of String/List

Map<String, List<String>> map = new HashMap<>();
map.put("product1", Arrays.asList("res1", "res2"));
map.put("product2", Arrays.asList("res1", "res2"));

Where the key is a letter, and the value is a list of "numbers"

Now what I´m trying to achieve is iterate over the map and return a map of "number" as key, and "letter" as value. Something like

     <"res1", List<"product1","product2" >>
     <"res2", List<"product1","product2" >>

For now I manage to do it, but in two steps, and the code seems pretty verbouse

@Test
public void test2() throws InterruptedException {

            List<String> restrictions = Arrays.asList("res1", "res2");
    Map<String, List<String>> productsRes = new HashMap<>();
    productsRes.put("product1", restrictions);
    productsRes.put("product2", restrictions);

    ArrayListMultimap multiMap = productsRes.keySet()
                                      .stream()
                                      .flatMap(productId -> productsRes.get(productId)
                                                                   .stream()
                                                                   .map(restriction -> {
                                                                       Multimap<String, List<String>> multimap = ArrayListMultimap.create();
                                                                       multimap.put(restriction, Arrays.asList(productId));
                                                                       return multimap;
                                                                   }))
                                      .collect(ArrayListMultimap::create, (map, restriction) -> map.putAll(restriction),
                                               ArrayListMultimap::putAll);
    Map<String, List<String>> resProducts = Multimaps.asMap(multiMap);

      }

Any suggestion?.

Thanks!

T. Neidhart
  • 6,060
  • 2
  • 15
  • 38
paul
  • 12,873
  • 23
  • 91
  • 153

1 Answers1

0

I would use a Multimap from guava and collect the results like that:

// the input map
Map<String, List<String>> lettersNumbers = new HashMap<>();
lettersNumbers.put("a", Arrays.asList("1", "2"));

// the output multimap
Multimap<String, String> result =
    lettersNumbers.entrySet()
                  .stream()
                  .collect(ArrayListMultimap::create,
                           (map, entry) -> {
                               entry.getValue().forEach((val) -> 
                                   map.put(val, entry.getKey()));
                           },
                           ArrayListMultimap::putAll);

The Multimap will contain the reverse mapping. If you want the result in a java.util.Map object, use Multimap.asMap().

T. Neidhart
  • 6,060
  • 2
  • 15
  • 38
  • Just fyi: guava already has a method to invert the mapping of a Multimap, see http://stackoverflow.com/questions/3678601/how-to-do-map-inversion-with-guava-with-non-unique-values. – T. Neidhart Jun 15 '16 at 19:48