2016-08-30 7 views
5

私はマップのリストの形式でデータ構造を持って設定します 私はJavaを使用して、単一のSetにリスト(マップの値)のすべての要素を収集するList< Map<String, List<String>> >Javaストリーム変換リストは

8の機能

例:

Input: [ {"a" : ["b", "c", "d"], "b" : ["a", "b"]}, {"c" : ["a", "f"]} ] 
Output: ["a", "b", "c", "d", "f"] 

感謝。最終collectにこれらのサブイタレーションを融合し、この目的の

List< Map<String, List<String>> > maps = ... 
Set<String> result = maps.stream() 
         .flatMap(m -> m.values().stream()) 
         .flatMap(List::stream) 
         .collect(Collectors.toSet()); 

答えて

10

あなたはStream.mapStream.flatMapのシリーズを使用することができます操作:

Set<String> output = input.stream() 
    .collect(HashSet::new, (set,map) -> map.values().forEach(set::addAll), Set::addAll); 
4

.flatMap based solutionsの代替のため

List<Map<String, List<String>>> input = ...; 

Set<String> output = input.stream() // -> Stream<Map<String, List<String>>> 
    .map(Map::values)     // -> Stream<List<List<String>>> 
    .flatMap(Collection::stream)  // -> Stream<List<String>> 
    .flatMap(Collection::stream)  // -> Stream<String> 
    .collect(Collectors.toSet())  // -> Set<String> 
    ; 
4

この問題には多くの選択肢があります。ここには、Eclipse Collectionsコンテナを使用して提供される他の回答の2つを含むいくつかの例があります。

MutableList<MutableMap<String, MutableList<String>>> list = 
     Lists.mutable.with(
       Maps.mutable.with(
         "a", Lists.mutable.with("b", "c", "d"), 
         "b", Lists.mutable.with("a", "b")), 
       Maps.mutable.with(
         "c", Lists.mutable.with("a", "f"))); 

ImmutableSet<String> expected = Sets.immutable.with("a", "b", "c", "d", "f"); 

// Accepted Streams solution 
Set<String> stringsStream = list.stream() 
     .map(Map::values) 
     .flatMap(Collection::stream) 
     .flatMap(Collection::stream) 
     .collect(Collectors.toSet()); 
Assert.assertEquals(expected, stringsStream); 

// Lazy Eclipse Collections API solution 
MutableSet<String> stringsLazy = list.asLazy() 
     .flatCollect(MutableMap::values) 
     .flatCollect(e -> e) 
     .toSet(); 
Assert.assertEquals(expected, stringsLazy); 

// Eager Eclipse Collections API solution 
MutableSet<String> stringsEager = 
     list.flatCollect(
       map -> map.flatCollect(e -> e), 
       Sets.mutable.empty()); 
Assert.assertEquals(expected, stringsEager); 

// Fused collect operation 
Set<String> stringsCollect = list.stream() 
     .collect(
       HashSet::new, 
       (set, map) -> map.values().forEach(set::addAll), 
       Set::addAll); 
Assert.assertEquals(expected, stringsCollect); 

// Fused injectInto operation 
MutableSet<String> stringsInject = 
     list.injectInto(
       Sets.mutable.empty(), 
       (set, map) -> set.withAll(map.flatCollect(e -> e))); 
Assert.assertEquals(expected, stringsInject); 

注:私はEclipse Collectionsのコミッターです。

関連する問題