7

I have the following map:

Map<DataFields, String> myMap;

But I need to convert it to the following:

Map<String, String> myMap;

My best feeble attempt which doesn't even compile is:

myMap.keySet().stream().map(k -> k.name()).collect(Collectors.toMap(k, v)
Mureinik
  • 297,002
  • 52
  • 306
  • 350
jiveturkey
  • 2,484
  • 1
  • 23
  • 41
  • 3
    I think you might need to use `entrySet()` instead of `keySet()`. – clinomaniac Feb 27 '18 at 18:43
  • not sure if FP reduces any efficiency. Another answer https://stackoverflow.com/questions/17208346/how-to-convert-mapobject-object-to-mapstring-string-in-java – Adesh Kumar Feb 27 '18 at 19:10
  • Also, not sure why you needed such a map. Wherever you have to use this map you could have effectively converted the key to string and then used. – Adesh Kumar Feb 27 '18 at 19:11

4 Answers4

9

You need to stream the entrySet() (so you have both the keys and the values), and collect them to a map:

Map<String, String> result =
    myMap.entrySet()
         .stream()
         .collect(Collectors.toMap(e -> e.getKey().name(), e -> e.getValue()));
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • 4
    `e -> e.getValue()` replace with `Entry::getValue` – Eugene Feb 27 '18 at 19:03
  • Eugene it's just a syntactic sugar. Any performance advantage of using `Entry::getValue` – Adesh Kumar Feb 27 '18 at 19:08
  • 1
    @AdeshKumar first, unless you tag me with `@`, I can't tell you commented, second is that a question or an affirmation? – Eugene Feb 27 '18 at 19:35
  • 1
    Yes, it's advantageous for both performance and readability to use method references where possible. – Louis Wasserman Feb 27 '18 at 19:43
  • 2
    @AdeshKumar a lambda expression will create one more synthetic method, while method references will not, that's about the only difference (besides readability) – Eugene Feb 27 '18 at 19:56
2
Map<String, String> result = myMap
    .entrySet() // iterate over all entries (object with tow fields: key and value)
    .stream() // create a stream
    .collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue()));
        // collect to map: convert enum Key value toString() and copy entry value
kasopey
  • 355
  • 4
  • 17
2

Another way of doing same without Collectors helper. Using entryset will make it very easy to map.

  map.entrySet()
                .stream()
                .collect(
                        () -> new HashMap<String, String>(),
                        (Map newMap, Map.Entry<DataFields, String> entry) -> {
                            newMap.put(entry.getKey().name(), entry.getValue());
                        }
                        ,
                        (Map map1, Map map2) -> {
                            map.putAll(map2);
                        }
                );
Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86
2

A Java 8, succint way to do it (without streams):

Map<String, String> result = new HashMap<>();
myMap.forEach((k, v) -> result.put(k.name(), v));
fps
  • 33,623
  • 8
  • 55
  • 110