Je recherche le moyen le plus simple de filtrer une collection. Je pense à quelque chose comme
Collection<?> foo = existingCollection.stream().filter( ... ). ...
Mais je ne sais pas quel est le meilleur moyen de passer du filtre à la restitution ou au remplissage d'une autre collection. La plupart des exemples semblent être "et ici vous pouvez imprimer". Il est possible qu'il y ait un constructeur ou une méthode de sortie qui me manque.
Il existe une raison pour laquelle la plupart des exemples évitent de stocker le résultat dans un Collection
. Ce n’est pas la méthode de programmation recommandée. Vous avez déjà un Collection
, celui qui fournit les données source et les collections ne sert à rien. Vous voulez effectuer certaines opérations dessus. Le cas idéal est donc d'exécuter l'opération à l'aide du flux et de ne pas stocker les données dans un Collection
intermédiaire. C’est ce que la plupart des exemples essaient de suggérer.
Bien sûr, de nombreuses API existantes fonctionnent avec Collection
s et le resteront toujours. Ainsi, l’API Stream
offre différentes manières de gérer la demande d’un objet Collection
.
Obtenez une implémentation List
arbitraire contenant le résultat:
List<T> results = l.stream().filter(…).collect(Collectors.toList());
Obtenez une implémentation Set
arbitraire contenant le résultat:
Set<T> results = l.stream().filter(…).collect(Collectors.toSet());
Obtenir un Collection
spécifique:
ArrayList<T> results =
l.stream().filter(…).collect(Collectors.toCollection(ArrayList::new));
Ajouter à un Collection
existant:
l.stream().filter(…).forEach(existing::add);
Créer un tableau:
String[] array=l.stream().filter(…).toArray(String[]::new);
Utilisez le tableau pour créer une liste avec un comportement spécifique (taille modifiable et fixe):
List<String> al=Arrays.asList(l.stream().filter(…).toArray(String[]::new));
Autorisez un flux capable parallèle à ajouter des listes locales temporaires et à les joindre ensuite:
List<T> results
= l.stream().filter(…).collect(ArrayList::new, List::add, List::addAll);
(Remarque: ceci est étroitement lié à la façon dont Collectors.toList()
est actuellement implémenté, mais c'est un détail d'implémentation, c'est-à-dire qu'il n'y a aucune garantie que les implémentations futures des collecteurs toList()
renverront toujours un ArrayList
)
Un exemple tiré de la documentation de Java.util.stream
:
List<String>results =
stream.filter(s -> pattern.matcher(s).matches())
.collect(Collectors.toList());
Collectors
a une méthode toCollection()
, je suggérerais de regarder de cette façon.
Par exemple, cela correspond davantage au style de programmation fonctionnelle Java 8:
Collection<String> a = Collections.emptyList();
List<String> result = a.stream().
filter(s -> s.length() > 0).
collect(Collectors.toList());