我有一个Map<String, List<String>>
映射,我想从中提取一个List<String>
,其中包含该映射中所有字符串列表的字符串。我想使用java8流语法。
在旧的Java中,我会这样做:
List<String> all = new LinkedList<String>();
for (String key: map.keySet()) {
all.addAll(map.get(key));
}
return all;
如何使用流来做到这一点?
答案 0 :(得分:7)
您可以使用Stream.flatMap(Function)
做您想做的事情。
public static List<String> collectValues(Map<String, List<String>> map) {
return map.values().stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
更通用的版本可能看起来像:
public static <E> List<E> collectValues(Map<?, ? extends Collection<? extends E>> map) {
return map.values().stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
还有一个更通用的版本,允许您指定返回类型:
public static <C extends Collection<E>, E> C collectValues(
Map<?, ? extends Collection<? extends E>> map, Supplier<C> collectionFactory) {
return map.values().stream()
.flatMap(Collection::stream)
.collect(Collectors.toCollection(collectionFactory));
}
最后,只是为了好玩,我能想到的最通用的版本:
public static <C, E> C collectValues(Map<?, ? extends Iterable<? extends E>> map,
Collector<E, ?, C> collector) {
return map.values().stream()
.flatMap(iterable -> StreamSupport.stream(iterable.spliterator(), false))
.collect(collector);
}
此人使用StreamSupport
类和Collector
界面。
答案 1 :(得分:4)
使用新的ArrayList和addAll()方法获得相同的结果。
ntdll.LdrpDoDebugBreak