使用 Java 流将字符串拆分为映射

Split String into Map using Java Streams

我想把下面的String拆分出来存到Map里

String = "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>>

地图的结构应该是这样的:

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

我目前只有将不同键值对相互拆分的逻辑,但我不知道如何实现将值相互拆分、删除括号和映射的逻辑属性。

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           
            )

您可以过滤具有两个值的数组,然后使用 Collectors.groupingBy to group the elements into Map, You can find more examples here 关于 groupingBy 和 `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())));

您的输入有两个 \r\n 来分隔条目,您也需要将其拆分,否则您将得到空条目,然后需要将其过滤掉。

在流中处理之前,我会从字符串中删除尖括号。 然后就只剩下收集这一步了。

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

另一种方法也可以拆分值列表:

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

试试这个。

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

输出

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