给出以下地图列表:
List<Map<String, Object>> list =new ArrayList();
Map<String, Object> map1 =new HashMap();
List<String> values =new ArrayList();
values.add("TEST");
values.add("TEST1");
map1.put("level",values);
Map<String, Object> map2 =new HashMap();
List<String> values2 =new ArrayList();
values2.add("TEST2");
values2.add("TEST3");
map2.put("level",values2);
list.add(map1);
list.add(map2);
我想要像平面字符串值列表一样的结果:
List<String> values = ["TEST","TEST1","TES2","TEST3"]
List<Object> collect = list
.stream()
.flatMap(x -> x.entrySet().stream())
.map(Map.Entry::getValue)
.flatMap(x -> {
if (x instanceof Collection<?>) {
return ((Collection<?>) x).stream();
} else {
return Stream.of(x);
}
}
)
.collect(Collectors.toList());
更改地图以输入值,例如
List<Map<String, List<String>>> list = new ArrayList<>();
Map<String, List<String>> map1 = new HashMap<>();
然后使用
flatMap()
两次对集合进行双重展平:
List<String> allValues = list.stream() // a stream of Maps
.map(Map::values) // a stream of Collection<List<String>>
.flatMap(Collection::stream) // a stream of List<String>
.flatMap(List::stream) // a stream of String
.collect(toList());
参见现场演示。
如果将地图的值保留为
Object
,则需要对它们进行强制转换:
List<String> allValues = list.stream() // a stream of Maps
.map(Map::values) // a stream of Collection<Object>
.map(o -> (Collection<List<String>>)o)
.flatMap(Collection::stream) // a stream of List<Object>
.map(o -> (List<String>)o)
.flatMap(List::stream) // a stream of String
.collect(toList());
如果正确输入,这会更丑陋、更不安全且不必要。
List<String> flattened = list.stream()
.flatMap(m -> m.values().stream())
.flatMap(l -> ((List<String>) l).stream())
.toList();
flatMap
来展平 Stream<Map<String, Object>>
的每个元素的值,从而得到 Stream<Object>
。然后,它在每个对象上再次调用 flatMap
,将它们转换为我们知道的 List<String>
,从而产生仅包含值字符串的 Stream<String>
。