问题
I want to convert the following
String flString="view1:filedname11,view1:filedname12,view2:fieldname21";
to a Map<String,Set<String>>
to get the key/value as below:
view1=[filedname11,filedname12]
view2=[fieldname21]
I want to use Java 8 streams. I tried
Arrays.stream(tokens)
.map(a -> a.split(":"))
.collect(Collectors.groupingBy(
a -> a[0], Collectors.toList()));
However the keys are also getting added to the value list.
回答1:
You should use a Collectors::mapping
to map the array to an element.
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);
Output
view1=[filedname11, filedname12]
view2=[fieldname21]
回答2:
You can use Collectors#toMap(keyMapper,valueMapper,mergeFunction) method as follows:
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]}
回答3:
Off course @K.Nicholas solution with using downstream collector is perfect.
But I additionally created another alternative solution that also uses Stream API. It is more complex and generates three streams, but it works too.
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);
回答4:
You can achieve your goal using the following piece of codes:
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())));
Simple output:
{view1=[filedname11, filedname12], view2=[fieldname21]}
来源:https://stackoverflow.com/questions/66055002/how-to-split-a-string-into-a-map-grouping-values-by-duplicate-keys-using-stream