Supposons que nous ayons une liste de pays: List<Country>
et que chaque pays ait une référence à une liste de ses régions: List<Region>
(par exemple, les États-Unis). Quelque chose comme ça:
USA
Alabama
Alaska
Arizona
...
Germany
Baden-Württemberg
Bavaria
Brandenburg
...
En Java "simple", nous pouvons compter toutes les régions, par exemple. par ici:
List<Country> countries = ...
int regionsCount = 0;
for (Country country : countries) {
if (country.getRegions() != null) {
regionsCount += country.getRegions().size();
}
}
Est-il possible d'atteindre le même objectif avec Java 8 Stream API? J'ai pensé à quelque chose de similaire, mais je ne sais pas comment compter les éléments des listes imbriquées à l'aide de la méthode count()
de l'API de flux:
countries.stream().filter(country -> country.getRegions() != null).???
Vous pouvez utiliser map()
pour obtenir une Stream
de listes de régions, puis mapToInt
pour obtenir le nombre de régions pour chaque pays. Après cela, utilisez sum()
pour obtenir la somme de toutes les valeurs de la IntStream
:
countries.stream().map(Country::getRegions) // now it's a stream of regions
.filter(rs -> rs != null) // remove regions lists that are null
.mapToInt(List::size) // stream of list sizes
.sum();
Remarque: L'avantage d'utiliser getRegions
avant le filtrage est qu'il n'est pas nécessaire d'appeler getRegions
plus d'une fois.
Vous pouvez mapper chaque pays sur le nombre de régions, puis réduire le résultat à l'aide de la somme:
countries.stream()
.map(c -> c.getRegions() == null ? 0 : c.getRegions().size())
.reduce(0, Integer::sum);
Vous pouvez même utiliser flatMap()
comme:
countries.stream().map(Country::getRegions).flatMap(List::stream).count();
where,
map(Country::getRegions) = returns a Stream<List<Regions>>
flatMap(List::stream) = returns a Stream<Regions>