【问题标题】:Split String into Map using Java Streams使用 Java Streams 将字符串拆分为 Map
【发布时间】:2021-04-21 20:10:44
【问题描述】:

我想把下面的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>"

字符串之间可以有换行符。一个键可以有多个值,这些值由, 分隔,以&lt; 开头,以&gt; 结尾。

现在需要将此字符串转换为Map&lt;String, List&lt;String&gt;&gt;

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

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           
            )

【问题讨论】:

    标签: java split hashmap java-stream


    【解决方案1】:

    您可以过滤具有两个值的数组,然后使用Collectors.groupingBy 将元素分组到Map,您可以找到更多关于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())));
    

    【讨论】:

      【解决方案2】:

      您的输入有两个\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]));
      

      【讨论】:

        【解决方案3】:

        另一种拆分值列表的方法:

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

        【讨论】:

          【解决方案4】:

          试试这个。

          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]}
          

          【讨论】:

            猜你喜欢
            • 2018-03-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-09-26
            • 2015-12-28
            相关资源
            最近更新 更多