Dans JDK 8 avec lambda b93, il y avait une classe java.util.stream.Streams.zip dans b93 qui pouvait être utilisée pour compresser les flux (ceci est illustré dans le tutoriel Exploring Java8 Lambdas. Part 1 par Dhananjay Nene ). Cette fonction:
Crée un Stream combiné paresseux et séquentiel dont les éléments sont le résultat de la combinaison des éléments de deux flux.
Cependant, en b98, cela a disparu. En fait, la Streams
classe n'est même pas accessible dans java.util.stream en b98 .
Cette fonctionnalité a-t-elle été déplacée, et si oui, comment puis-je compresser les flux de manière concise en utilisant b98?
L'application que j'ai en tête se trouve dans cette implémentation java de Shen , où j'ai remplacé la fonctionnalité zip dans le
static <T> boolean every(Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred)
static <T> T find(Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred)
fonctions avec un code assez verbeux (qui n'utilise pas les fonctionnalités de b98).
Réponses:
J'en avais besoin aussi, alors j'ai juste pris le code source de b93 et l'ai mis dans une classe "util". J'ai dû le modifier légèrement pour fonctionner avec l'API actuelle.
Pour référence, voici le code de travail (prenez-le à vos risques et périls ...):
la source
SIZED
si l'un ou l'autre des flux estSIZED
, pas les deux?SIZED
pour que cette implémentation fonctionne. Cela dépend en fait de la façon dont vous définissez la compression. Devriez-vous être capable de compresser deux flux de taille différente, par exemple? À quoi ressemblerait alors le flux résultant? Je pense que c'est pourquoi cette fonction a été omise de l'API. Il existe de nombreuses façons de faire cela et c'est à l'utilisateur de décider quel comportement doit être le "correct". Souhaitez-vous supprimer les éléments du flux le plus long ou compléter la liste la plus courte? Si oui, avec quelle (s) valeur (s)?Spliterator<A>
).zip est l'une des fonctions fournies par la bibliothèque protonpack .
la source
Si vous avez Guava dans votre projet, vous pouvez utiliser la méthode Streams.zip (a été ajoutée dans Guava 21):
la source
Zipper deux flux en utilisant JDK8 avec lambda ( gist ).
la source
import java.util.function.*;
etimport java.util.stream.*;
en haut de votre fichier.() -> iterator
et là encore:iterable.spliterator()
. Pourquoi ne pas implémenter directement unSpliterator
plutôt qu'unIterator
? Vérifiez @Doradus réponse stackoverflow.com/a/46230233/1140754Étant donné que je ne peux concevoir aucune utilisation de la compression sur des collections autres que celles indexées (Lists) et que je suis un grand fan de simplicité, ce serait ma solution:
la source
mapToObject
devrait êtremapToObj
.RandomAccess
(par exemple sur les listes chaînées), ce sera très lentLes méthodes de la classe que vous avez mentionnée ont été déplacées vers l'
Stream
interface elle-même au profit des méthodes par défaut. Mais il semble que lazip
méthode ait été supprimée. Peut-être parce que le comportement par défaut des flux de différentes tailles n'est pas clair. Mais la mise en œuvre du comportement souhaité est simple:la source
predicate
vous avez passé au filtre avec état ? Cela viole le contrat de méthode et ne fonctionnera surtout pas lors du traitement du flux en parallèle.Je suggère humblement cette mise en œuvre. Le flux résultant est tronqué au plus court des deux flux d'entrée.
la source
.., leftStream.isParallel() || rightStream.isParallel()
. Je pense que cela n'a aucun effet carAbstractSpliterator
offre un parallélisme limité par défaut. Je pense donc que le résultat final sera le même que celui de passerfalse
.La bibliothèque Lazy-Seq fournit la fonctionnalité zip.
https://github.com/nurkiewicz/LazySeq
Cette bibliothèque est fortement inspirée
scala.collection.immutable.Stream
et vise à fournir une implémentation de séquence paresseuse immuable, sûre pour les threads et facile à utiliser, éventuellement infinie.la source
En utilisant la dernière bibliothèque Guava (pour la
Streams
classe), vous devriez pouvoir fairela source
Cela fonctionnerait-il pour vous? C'est une fonction courte, qui évalue paresseusement les flux qu'elle zippe, vous pouvez donc lui fournir des flux infinis (elle n'a pas besoin de prendre la taille des flux compressés).
Si les flux sont finis, il s'arrête dès que l'un des flux manque d'éléments.
Voici un code de test unitaire (beaucoup plus long que le code lui-même!)
la source
takeWhile
à la fin, c'était que cela ne semble pas être dans java8 mais ce n'est pas un problème car l'appelé peut filtrer toutes les valeurs nulles qui se produisent lorsque les flux compressés ne sont pas de la même taille. Je pense que cette réponse devrait être la réponse numéro 1 car elle est cohérente et compréhensible. excellent travail merci encore.la source
Le cyclope- react d' AOL , auquel je contribue, fournit également des fonctionnalités de compression, à la fois via une implémentation de Stream étendue , qui implémente également l'interface de flux réactifs ReactiveSeq, et via StreamUtils qui offre une grande partie des mêmes fonctionnalités via des méthodes statiques aux flux Java standard.
Il offre également une fermeture éclair plus généralisée basée sur l'application. Par exemple
Et même la possibilité d'associer chaque élément d'un flux avec chaque élément d'un autre
la source
Si quelqu'un en a encore besoin, il y a une
StreamEx.zipWith
fonction dans la bibliothèque streamex :la source
C'est bien. J'ai dû compresser deux flux dans une carte avec un flux étant la clé et l'autre la valeur
Sortie: {A = pomme, B = banane, C = carotte}
la source