我有一个包含两个字符串的数组的数组。
var array = new String[][]{
{"a", "1"},
{"a", "2"},
{"b", "3"},
...
};
我如何将上面的数组收集到一个Map<String, Set<String>>
,其键是每个数组的第一个元素,值是数组的第二个元素的集合?
让我得到下面的地图?
// Map<String, Set<String>>
<"a", ["1, "2"]>,
<"b", ["3"]>,
...
到目前为止,我发现可以像这样对每个数组的第一个元素进行分类。
Arrays.stream(array).collect(Collectors.groupingBy(
a -> ((String[])a)[0],
// how can I collect the downstream?
);
您可以在下游使用Collectors.mapping()
和toSet()
:
Collectors.groupingBy(a -> a[0],
Collectors.mapping(v -> v[1], Collectors.toSet()))
生成{a=[1, 2], b=[3]}
。首先将流元素映射到数组的第二个元素,然后将这些元素作为映射到组键的集合收集。
将Collectors.groupingBy
与Collectors.mapping()
结合使用。
public static void main(String[] args) {
var array = new String[][]{
{"a", "1"},
{"a", "2"},
{"b", "3"}
};
Map<String, Set<String>> result =
Stream.of(array)
.collect(Collectors.groupingBy(arr -> arr[0],
Collectors.mapping(arr -> arr[1],
Collectors.toSet())));
System.out.println(result);
}
另一种方法是使用Collector.of()
:
Map<String, Set<String>> result =
Stream.of(array)
.collect(Collector.of(
HashMap::new,
(Map<String, Set<String>> map, String[] arr) ->
map.computeIfAbsent(arr[0], k -> new HashSet<>()).add(arr[1]),
(Map<String, Set<String>> left, Map<String, Set<String>> right) ->
{ left.putAll(right); return left; }));
{a=[1, 2], b=[3]}
你需要一个Collectors.mapping
(也不需要在里面指定String[]
)
var array = new String[][]{{"a", "1"}, {"a", "2"}, {"b", "3"},};
Map<String, Set<String>> res = Arrays.stream(array).collect(Collectors.groupingBy(
a -> a[0],
Collectors.mapping(a -> a[1], Collectors.toSet())
));
System.out.println(res); // {a=[1, 2], b=[3]}
您可以简单地使用for-each循环
Map<String, Set<String>> map=new HashMap<>();
for(String []arr : array){
Set<String> set = map.getOrDefault(arr[0], new HashSet<>());
set.add(arr[1]);
map.put(arr[0],set);
}
System.out.println(map);
输出:
{a=[1, 2], b=[3]}
您可以使用Collectors.toMap
代替Collectors.groupingBy
。
public class Main {
public static void main(String[] args) throws Exception {
String[][] array = new String[][]{{"a", "1"}, {"a", "2"}, {"b", "3"}};
Map<String, Set<String>> map = Arrays.stream(array).collect(Collectors.toMap(
arr -> arr[0],
arr -> new HashSet<>(Collections.singleton(arr[1])),
(l, r) -> {
l.addAll(r);
return l;
}));
System.out.println(map);
}
}
第一个参数为keyMapper
,第二个参数为valueMapper
,第三个参数为mergeFunction
。
你可以循环遍历你的数组对于每个字符你可以检查这个键是否在你的映射中保存过,如果是只需将对应的字符推入重复键的列表