Je jouais avec des lambdas Java 8 pour filtrer facilement les collections. Mais je n'ai pas trouvé de moyen concis pour récupérer le résultat sous la forme d'une nouvelle liste dans la même déclaration. Voici mon approche la plus concise à ce jour:
List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List<Long> targetLongList = new ArrayList<>();
sourceLongList.stream().filter(l -> l > 100).forEach(targetLongList::add);
Les exemples sur le net n'ont pas répondu à ma question car ils s'arrêtent sans générer de nouvelle liste de résultats. Il doit y avoir un moyen plus concis. Je me serais attendu, que la Stream
classe a des méthodes comme toList()
, toSet()
...
Existe-t-il un moyen d' targetLongList
affecter directement les variables par la troisième ligne?
collections
lambda
java-8
java-stream
Daniel K.
la source
la source
sourceLongList
suite, c'estCollection.removeIf(…)
pour plus de commodité.List<Long> targetLongList = sourceLongList.stream().collect(Collectors.toList());
Réponses:
Ce que vous faites peut être le moyen le plus simple, à condition que votre flux reste séquentiel, sinon vous devrez auparavant appeler séquentiel ()
forEach
.[édition ultérieure: la raison pour laquelle l'appel à sequential () est nécessaire est que le code tel qu'il est (
forEach(targetLongList::add)
) serait racé si le flux était parallèle. Même alors, il n'obtiendra pas l'effet escompté, comme celaforEach
est explicitement non déterministe - même dans un flux séquentiel, l'ordre de traitement des éléments n'est pas garanti. Vous devrez utiliserforEachOrdered
pour assurer une commande correcte. L'intention des concepteurs d'API Stream est que vous utilisiez le collecteur dans cette situation, comme ci-dessous.]Une alternative est
la source
toList
. Cela se fait en plaçant les éléments suivants parmi les importations du fichier:static import java.util.stream.Collectors.toList;
. Ensuite, l'appel de collecte lit simplement.collect(toList())
.Collectors
classe dans Préférences -> Java -> Éditeur -> Assistant de contenu -> Favoris . Après cela, il vous suffit de tapertoLi
au hit Ctr + Space pour que l'IDE remplissetoList
et ajoute l'importation statique.IntStream
et certains autres presque mais pas tout à faitStream
n'ont pas lacollect(Collector)
méthode et vous devrez d'abord appelerIntStream.boxed()
pour les convertir en une version régulièreStream
. Là encore, peut-être que vous voulez justetoArray()
.sequential()
avantforEach
ou utiliser 'forEachOrdered`Mise à jour:
Une autre approche consiste à utiliser
Collectors.toList
:Solution précédente:
Une autre approche consiste à utiliser
Collectors.toCollection
:la source
Collectors::toList
javadoc: "Il n'y a aucune garantie sur le type, la mutabilité, la sérialisation ou la sécurité des threads de la liste retournée; si plus de contrôle sur la liste retournée est nécessaire, utiliseztoCollection(Supplier)
."J'aime utiliser une méthode util qui retourne un collecteur
ArrayList
quand c'est ce que je veux.Je pense que la solution utilisée
Collectors.toCollection(ArrayList::new)
est un peu trop bruyante pour une opération aussi courante.Exemple:
Avec cette réponse, je veux également démontrer à quel point il est simple de créer et d'utiliser des collecteurs personnalisés, ce qui est très utile en général.
la source
toList
si vous voulez par exemple modifier la liste plus tard dans le programme. LatoList
documentation dit ceci: "Il n'y a aucune garantie sur le type, la mutabilité, la sérialisation ou la sécurité des threads de la liste renvoyée; si un plus grand contrôle sur la liste retournée est requis, utiliseztoCollection
." . Ma réponse montre un moyen de rendre plus pratique de le faire dans un cas commun.Si vous disposez d'un tableau de primitives, vous pouvez utiliser les collections de primitives disponibles dans les collections Eclipse .
Si vous ne pouvez pas modifier la sourceLongList de
List
:Si vous souhaitez utiliser
LongStream
:Remarque: je suis un contributeur aux collections Eclipse.
la source
Un moyen un peu plus efficace (évitez la création de la liste source et la décompression automatique par le filtre):
la source
Il s'agit de l'appel que vous pouvez utiliser pour convertir n'importe quel flux en liste.
plus concrètement:
de:
https://www.geeksforgeeks.org/collectors-tolist-method-in-java-with-examples/
la source
Si cela ne vous dérange pas d'utiliser des bibliothèques tierces, la lib cyclops-react d'AOL (divulgation, je suis un contributeur) a des extensions pour tous les types de collections JDK , y compris List . L'interface ListX étend java.util.List et ajoute un grand nombre d'opérateurs utiles, y compris le filtre.
Vous pouvez simplement écrire-
ListX peut également être créé à partir d'une liste existante (via ListX.fromIterable)
la source
Il existe une autre variante de la méthode de collecte fournie par la classe LongStream et également par les classes IntStream et DoubleStream.
Effectue une opération de réduction mutable sur les éléments de ce flux. Une réduction modifiable est une réduction dans laquelle la valeur réduite est un conteneur de résultat modifiable, tel qu'une liste de tableaux, et les éléments sont incorporés en mettant à jour l'état du résultat plutôt qu'en remplaçant le résultat. Cela produit un résultat équivalent à:
Comme réduire (long, LongBinaryOperator), les opérations de collecte peuvent être parallélisées sans nécessiter de synchronisation supplémentaire. Il s'agit d'une opération de terminal.
Et la réponse à votre question avec cette méthode de collecte est la suivante:
Vous trouverez ci-dessous la variante de référence de la méthode qui est assez intelligente, mais certaines sont difficiles à comprendre:
Ci-dessous sera la variante HashSet:
De même, la variante LinkedList est comme ceci:
la source
Dans le cas où quelqu'un (comme moi) cherche des moyens de traiter les objets au lieu des types primitifs, utilisez
mapToObj()
impressions:
la source
la source
Voici le code d' AbacusUtil
Divulgation : Je suis le développeur d'AbacusUtil.
la source
com.landawn.abacus.util.stream.LongStream
orLongStreamEx
in AbacusUtilVous pouvez réécrire le code comme ci-dessous:
la source
Pour collecter dans une liste mutable:
Pour collecter dans une liste immuable:
Explication de
collect
la JavaDoc :la source
Si vous n'utilisez pas
parallel()
cela fonctionnerala source
collect
et de ne pas enregistrer la valeur de retour. Dans ce cas, vous pouvez utiliser à laforEach
place. Mais c'est toujours une mauvaise solution.