Istnieje wiele alternatyw dla tego problemu. Oto kilka z dwóch innych odpowiedzi dostarczonych z użyciem kontenerów Eclipse Collections.
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);
Uwaga: jestem uczestnikiem kolekcji Eclipse.