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?

6
  • Take a look at the flatMap's documentation. Commented Oct 8, 2018 at 4:35
  • 3
    You can't, because if you replace utilMap.put("2","2"); with utilMap.put(",=",",=,=");, then you end up with 1=1,,==,=,=,3=3,4=4,5=5, and that is irreversible. Commented Oct 8, 2018 at 4:38
  • If I use Map <Long, Long> then I can not @Andreas Commented Oct 8, 2018 at 4:55
  • 1
    @PhuongLinh But your question is using Map<String, String> Commented Oct 8, 2018 at 4:57
  • @Andreas I also can flexibly switch to HashMap <Long, Long> form Commented Oct 8, 2018 at 12:26

4 Answers 4

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}

Sign up to request clarification or add additional context in comments.

4 Comments

Comma is not a regex special character, so no need to escape it.
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.
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])
Not NullPointerException it will throw ArrayIndexOutOfBoundException
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}]

1 Comment

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.
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]));

Comments

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));

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.