web-dev-qa-db-fra.com

API Java Stream - Compter les éléments d'une liste imbriquée

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).???
13
dominik

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.

27
fabian

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);
5
Vasily Liaskovsky

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>
0
Ram Patra