【问题标题】:java 8 streams how to convert a Map<String, List<Strings>> to a List<String> will all the string values?java 8 流如何将 Map<String, List<Strings>> 转换为 List<String> 将所有字符串值?
【发布时间】:2018-08-19 18:32:28
【问题描述】:

我有一个Map&lt;String, List&lt;String&gt;&gt; 映射,我想从中提取一个List&lt;String&gt;,其中包含映射中所有字符串列表的字符串。我想使用 java8 流语法。

在旧的 java 中我会这样做:

List<String> all = new LinkedList<String>();
for (String key: map.keySet()) {
    all.addAll(map.get(key));
}
return all;

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

【问题讨论】:

  • map.values().stream().flatMap(List::stream).collect(Collectors.toList())
  • 其实,在 java 8 之前你宁愿做for (List&lt;String&gt; value : map.values()) {all.addAll(value);}

标签: java java-8 java-stream


【解决方案1】:

你可以使用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接口。

【讨论】:

    【解决方案2】:

    使用新的 ArrayList 和 addAll() 方法得到相同的结果。

    public class MapTest {
        public static void main(String[] args) {
            Map<String, List<String>> infoMap = new HashMap<>();
            infoMap.put("1", Arrays.asList("a","b","c"));
            infoMap.put("2", Arrays.asList("d","e","f"));
            infoMap.put("3", Arrays.asList("g","h","i"));
    
            List<String> result = new ArrayList<>();
            infoMap.values().stream().forEach(result::addAll);
            result.forEach(System.out::println);
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-30
      • 2020-03-17
      • 1970-01-01
      • 2019-07-31
      • 1970-01-01
      相关资源
      最近更新 更多