使用流 API 将数组的散列映射合并到数组中
combine hashmaps of Arrays into array using stream API
假设我有一个整数映射的映射,我想过滤第二个映射的键并组合给定键的数组。
所以基本上我想从
Map<String, Map<String, List<Integer>>>
到
List<Integer>
例如
KeyA -> keya -> [1,2,3]
KeyB -> keya -> [4,5,6]
KeyC -> keyb -> [7,8]
结果应该是如果过滤值是keya [1,2,3,4,5,6],我不太关心第一组键。
我以标准的迭代方式完成此操作没有任何问题。
不过我想使用 Streams。
您的描述有误,地图中不能有两个名为 "keya"
的相同键。
但是,Stream API 的常见解决方案如下所示:
List<Integer> collect = source.values().stream()
.flatMap(s -> s.entrySet().stream())
.filter(s1 -> s1.getKey().equals(1) || s1.getKey().equals(2)) //needed key here
.map(Map.Entry::getValue)
.flatMap(Collection::stream)
.collect(Collectors.toList());
例如:
Map<String, Map<Integer, List<Integer>>> source = Map.of("keyA", Map.of(1, Arrays.asList(1,2,3,5)), "keyB", Map.of(2, Arrays.asList(5,6,7,8)));
输出:
[5,6,7,8,1,2,3,5]
你可以这样做:
List<Integer> list = m
.values()
.stream()
.flatMap(innerMap ->
innerMap
.entrySet()
.stream()
.filter(entry -> entry.getKey().equals(1))
.flatMap(entry -> entry.getValue().stream()))
.collect(Collectors.toList());
如果要过滤内层map的key,可以这样:
static List<Integer> findByKey(Map<String, Map<String, List<Integer>>> map, String key) {
return map.values()
.stream() // Stream<Map<String, List<Integer>>>
.flatMap(v -> v.entrySet().stream()) // Stream<Map.Entry<String, List<Integer>>>
.filter(e -> key.equals(e.getKey()))
.flatMap(e -> e.getValue().stream()) // Stream<Integer>
.collect(Collectors.toList());
}
测试
Map<String, Map<String, List<Integer>>> map = Map.of(
"KeyA", Map.of("keya", Arrays.asList(1, 2, 3)),
"KeyB", Map.of("keya", Arrays.asList(4, 5, 6)),
"KeyC", Map.of("keyb", Arrays.asList(7, 8))
);
System.out.println(findByKey(map, "keya"));
输出随机变化
[4, 5, 6, 1, 2, 3]
or
[1, 2, 3, 4, 5, 6]
由于输入映射未排序,此输出随机出现混合顺序,这可以通过对输入映射的 entrySet 流进行排序来解决:
static List<Integer> findByKeySorted(Map<String, Map<String, List<Integer>>> map, String key) {
return map.entrySet()
.stream() // Stream<Map.Entry<String, Map<List<Integer>>>>
.sorted(Map.Entry.comparingByKey())
.map(e -> e.getValue().get(key)) // Stream<List<Integer>>
.filter(Objects::nonNull)
.flatMap(List::stream) // Stream<Integer>
.collect(Collectors.toList());
}
System.out.println(findByKeySorted(map, "keya"));
输出(稳定):
[1, 2, 3, 4, 5, 6]
假设我有一个整数映射的映射,我想过滤第二个映射的键并组合给定键的数组。
所以基本上我想从
Map<String, Map<String, List<Integer>>>
到
List<Integer>
例如
KeyA -> keya -> [1,2,3]
KeyB -> keya -> [4,5,6]
KeyC -> keyb -> [7,8]
结果应该是如果过滤值是keya [1,2,3,4,5,6],我不太关心第一组键。
我以标准的迭代方式完成此操作没有任何问题。
不过我想使用 Streams。
您的描述有误,地图中不能有两个名为 "keya"
的相同键。
但是,Stream API 的常见解决方案如下所示:
List<Integer> collect = source.values().stream()
.flatMap(s -> s.entrySet().stream())
.filter(s1 -> s1.getKey().equals(1) || s1.getKey().equals(2)) //needed key here
.map(Map.Entry::getValue)
.flatMap(Collection::stream)
.collect(Collectors.toList());
例如:
Map<String, Map<Integer, List<Integer>>> source = Map.of("keyA", Map.of(1, Arrays.asList(1,2,3,5)), "keyB", Map.of(2, Arrays.asList(5,6,7,8)));
输出:
[5,6,7,8,1,2,3,5]
你可以这样做:
List<Integer> list = m
.values()
.stream()
.flatMap(innerMap ->
innerMap
.entrySet()
.stream()
.filter(entry -> entry.getKey().equals(1))
.flatMap(entry -> entry.getValue().stream()))
.collect(Collectors.toList());
如果要过滤内层map的key,可以这样:
static List<Integer> findByKey(Map<String, Map<String, List<Integer>>> map, String key) {
return map.values()
.stream() // Stream<Map<String, List<Integer>>>
.flatMap(v -> v.entrySet().stream()) // Stream<Map.Entry<String, List<Integer>>>
.filter(e -> key.equals(e.getKey()))
.flatMap(e -> e.getValue().stream()) // Stream<Integer>
.collect(Collectors.toList());
}
测试
Map<String, Map<String, List<Integer>>> map = Map.of(
"KeyA", Map.of("keya", Arrays.asList(1, 2, 3)),
"KeyB", Map.of("keya", Arrays.asList(4, 5, 6)),
"KeyC", Map.of("keyb", Arrays.asList(7, 8))
);
System.out.println(findByKey(map, "keya"));
输出随机变化
[4, 5, 6, 1, 2, 3]
or
[1, 2, 3, 4, 5, 6]
由于输入映射未排序,此输出随机出现混合顺序,这可以通过对输入映射的 entrySet 流进行排序来解决:
static List<Integer> findByKeySorted(Map<String, Map<String, List<Integer>>> map, String key) {
return map.entrySet()
.stream() // Stream<Map.Entry<String, Map<List<Integer>>>>
.sorted(Map.Entry.comparingByKey())
.map(e -> e.getValue().get(key)) // Stream<List<Integer>>
.filter(Objects::nonNull)
.flatMap(List::stream) // Stream<Integer>
.collect(Collectors.toList());
}
System.out.println(findByKeySorted(map, "keya"));
输出(稳定):
[1, 2, 3, 4, 5, 6]