7

I have a Map:

Map<String, String> utilMap = new HashMap();
utilMap.put("1","1");
utilMap.put("2","2");
utilMap.put("3","3");
utilMap.put("4","4");

I converted it to a String:

String utilMapString = utilMap
                .entrySet()
                .stream()
                .map(e -> e.toString()).collect(Collectors.joining(","));
Out put: 1=1,2=2,3=3,4=4,5=5

How to convert utilMapString to Map in Java8? Who can help me with?

Phuong
  • 329
  • 2
  • 7
  • 15

4 Answers4

17

Split the string by , to get individual map entries. Then split them by = to get the key and the value.

Map<String, String> reconstructedUtilMap = Arrays.stream(utilMapString.split(","))
            .map(s -> s.split("="))
            .collect(Collectors.toMap(s -> s[0], s -> s[1]));

Note: As pointed out by Andreas@ in the comments, this is not a reliable way to convert between a map and a string

EDIT: Thanks to Holger for this suggestion.

Use s.split("=", 2) to ensure that the array is never larger than two elements. This will be useful to not lose the contents (when the value has =)

Example: when the input string is "a=1,b=2,c=3=44=5555" you will get {a=1, b=2, c=3=44=5555}

Earlier (just using s.split("=")) will give {a=1, b=2, c=3}

Thiyagu
  • 17,362
  • 5
  • 42
  • 79
  • 1
    Comma is not a regex special character, so no need to escape it. – Andreas Oct 08 '18 at 04:58
  • 4
    Use `s.split("=", 2)` to ensure that the array is never larger than two elements. While we can’t fix ambiguous `=` characters, we can prevent losing contents when there are more of them. – Holger Oct 08 '18 at 07:14
  • If this is the case `a=1,b=` the above code will throw NullPointerException how we can address the null pointer issue `Collectors.toMap(s -> s[0], s -> s[1])` – Jatinder Apr 06 '22 at 13:57
  • Not NullPointerException it will throw ArrayIndexOutOfBoundException – Jatinder Apr 06 '22 at 14:04
1

Here is another option which streams a list of 1=1 etc. terms into a map.

String input = "1=1,2=2,3=3,4=4,5=5";
Map<String, String> map = Arrays.asList(input.split(",")).stream().collect(
             Collectors.toMap(x -> x.replaceAll("=\\d+$", ""),
                 x -> x.replaceAll("^\\d+=", "")));
System.out.println(Collections.singletonList(map));

[{1=1, 2=2, 3=3, 4=4, 5=5}]
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • Why not `x.replaceFirst("=.*", "")` and `x.replaceFirst(".*=", "")`? Still heavy compared to `x.substring(0, x.indexOf('='))` and `x.substring(x.indexOf('=')+1)`, but not trying to bend `replaceAll`’s behavior towards `replaceFirst` behavior via regex. – Holger Oct 08 '18 at 08:06
0

If you want to generate a map from String you can it with below way:

Map<String, String> newMap = Stream.of(utilMapString.split("\\,"))
            .collect(Collectors.toMap(t -> t.toString().split("=")[0], t -> t.toString().split("=")[1]));
Amit
  • 1,540
  • 1
  • 15
  • 28
0

If the sequence may contain values with the same key - use

Map<String, String> skipDuplicatesMap = Stream.of("1=1,2=2,3=3,4=4,5=5".split(",")).
            map(el -> el.split("=")).
            collect(toMap(arr -> arr[0], arr -> arr[1], (oldValue, newValue) -> oldValue));
Azee
  • 1,809
  • 17
  • 23