1

I want to split the following String and store it into a Map.

String = "key_a:<value_a1>\r\n\r\nkey_b:<value_b1>\r\n\r\nkey_c:<value_c1, value_c2, value_c3>"

The string can have line breaks in between the pairs. A key can have multiple values that are separated by a , and begin with a < and end with a >.

Now this String needs to be converted to a Map<String, List<String>>.

The structure of the map should look like this:

key_a={value_a1}, 
key_b={value_b1}, 
key_c={value_c1, value_c2, value_c3}

I currently only have the logic for splitting apart the different key-value-pairs from each other, but I don't know how to implement the logic that splits the values apart from each other, removes the brackets and maps the attributes.

String strBody = "key_a:<value_a1>\r\n\r\nkey_b:<value_b1>\r\n\r\nkey_c:<value_c1, value_c2, value_c3>"

Map<String, List<String>> map = Pattern.compile("\\r?\\n")
            .splitAsStream(strBody)
            .map(s -> s.split(":"))
               //...logic for splitting values apart from each other, removing <> brackets and storing it in the map           
            )

4 Answers 4

2

You can filter the arrays having two values and then use Collectors.groupingBy to group the elements into Map, You can find more examples here about groupingBy and `mapping

 Map<String, List<String>> map = Pattern.compile("\\r?\\n")
            .splitAsStream(strBody)
            .map(s -> s.split(":"))
            .filter(arr -> arr.length == 2)
            .collect(Collectors.groupingBy(arr -> arr[0],
                    Collectors.mapping(arr -> arr[1].replaceAll("[<>]", ""), 
                            Collectors.toList())));
Sign up to request clarification or add additional context in comments.

Comments

1

An additional approach which also splits the list of values:

Map<String,List<String>> result = 
     Pattern.compile("[\\r\\n]+")
        .splitAsStream(strBody)
        .map(s -> s.split(":"))
        .map(arr -> new AbstractMap.SimpleEntry<>(
                            arr[0],
                            Arrays.asList(arr[1].replaceAll("[<>]", "").split("\\s*,\\s"))))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Comments

0

Your input has two \r\n to separate the entries, you need to split it by it as well, otherwise you will get empty entries, which you then need to filter out.

I'd remove the angle brackets from the string before processing it in the stream. And then only the step of collection remains.

Map<String, String> map = Pattern.compile("\\r?\\n\\r?\\n")
    .splitAsStream(strBody.replaceAll("[<>]",""))
    .map(s -> s.split(":"))
    .collect(Collectors.toMap(e -> e[0], e-> e[1]));

Comments

0

Try this.

String strBody = "key_a:<value_a1>\r\n\r\nkey_b:<value_b1>\r\n\r\nkey_c:<value_c1, value_c2, value_c3>";
Map<String, List<String>> result = Arrays.stream(strBody.split("\\R\\R"))
    .map(e -> e.split(":", 2))
    .collect(Collectors.toMap(a -> a[0],
        a -> List.of(a[1].replaceAll("^<|>$", "").split("\\s,\\s*"))));
System.out.println(result);

output

{key_c=[value_c1, value_c2, value_c3], key_b=[value_b1], key_a=[value_a1]}

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.