java 8流如何将Map <string,list <strings =“” >>转换为List <string>将所有字符串值转换?

时间:2018-08-19 18:32:29

标签: java java-8 java-stream

我有一个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;

如何使用流来做到这一点?

2 个答案:

答案 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