如何将一个字符串分割成一个映射,通过使用流的重复键分组值?



我想转换以下内容

String flString="view1:filedname11,view1:filedname12,view2:fieldname21";

Map<String,Set<String>>获取键/值,如下:

view1=[filedname11,filedname12]
view2=[fieldname21]

我想使用Java 8流。我试着

Arrays.stream(tokens)
.map(a -> a.split(":"))
.collect(Collectors.groupingBy(
a -> a[0], Collectors.toList()));

但是键也被添加到值列表中。

您应该使用Collectors::mapping将数组映射到元素。

String flString = "view1:filedname11,view1:filedname12,view2:fieldname21";
Map<String, List<String>> map = Pattern.compile(",")
.splitAsStream(flString)
.map(a -> a.split(":"))
.collect(
Collectors.groupingBy(a -> a[0],
Collectors.mapping(a -> a[1], Collectors.toList())
)
);
map.entrySet().forEach(System.out::println);

输出

view1=[filedname11, filedname12]
view2=[fieldname21]

Collectors#toMap(keyMapper,valueMapper,mergeFunction)方法的使用方法如下:

String flString = "view1:filedname11,view1:filedname12,view2:fieldname21";
Map<String, Set<String>> map = Arrays
.stream(flString.split(","))
.map(str -> str.split(":"))
.collect(Collectors.toMap(
arr -> arr[0],
arr -> new HashSet<>(Set.of(arr[1])),
(s1, s2) -> {
s1.addAll(s2);
return s1;
}));
System.out.println(map);
// {view1=[filedname11, filedname12], view2=[fieldname21]}

偏离轨道@K。Nicholas解决方案使用下游收集器是完美的。

但我另外创建了另一个替代解决方案,也使用流API。它更复杂,产生三个流,但它也能工作。

String flString = "view1:filedname11,view1:filedname12,view2:fieldname21";
Map<String, Set<String>> map1 =
Arrays.stream(flString.split(","))
.map(a -> a.split(":"))
.collect(Collectors.toMap(
a -> a[0],
a -> a[1],
(a1, a2) -> a1 + "," + a2))
.entrySet().stream()
.collect(Collectors.toMap(
e -> e.getKey(),
e -> Arrays.stream(e.getValue().split(","))
.collect(Collectors.toSet())));
map1.entrySet().forEach(System.out::println);

您可以使用下面的代码实现您的目标:

String flString = "view1:filedname11,view1:filedname12,view2:fieldname21";
Map<String, List<String>> collect = Stream.of(flString)
.flatMap(str -> Stream.of(str.split(",")))
.map(keyValuePair -> keyValuePair.split(":"))
.collect(Collectors.groupingBy(it -> it[0], Collectors.mapping(it -> it[1], Collectors.toList())));

简单输出:

{view1=[filedname11, filedname12], view2=[fieldname21]}

最新更新