Je sais qu'il n'y a pas d'équivalent direct dans Java lui-même, mais peut-être un tiers?
C'est vraiment pratique. Actuellement, j'aimerais implémenter un itérateur qui donne tous les nœuds dans un arbre, soit environ cinq lignes de code avec rendement.
java
yield
yield-return
ripper234
la source
la source
Réponses:
Les deux options que je connais sont la bibliothèque infomancers-collections d'Aviad Ben Dov de 2007 et la bibliothèque YieldAdapter de Jim Blackler de 2008 (qui est également mentionnée dans l'autre réponse).
Les deux vous permettront d'écrire du code avec une
yield return
construction -like en Java, donc les deux satisferont votre demande. Les différences notables entre les deux sont:Mécanique
La bibliothèque d'Aviad utilise la manipulation de bytecode tandis que celle de Jim utilise le multithreading. En fonction de vos besoins, chacun peut avoir ses propres avantages et inconvénients. Il est probable que la solution d'Aviad soit plus rapide, tandis que celle de Jim est plus portable (par exemple, je ne pense pas que la bibliothèque d'Aviad fonctionnera sur Android).
Interface
La bibliothèque d'Aviad a une interface plus propre - voici un exemple:
Alors que Jim est beaucoup plus compliqué, vous obligeant à
adept
un génériqueCollector
qui a unecollect(ResultHandler)
méthode ... ugh. Cependant, vous pouvez utiliser quelque chose comme ce wrapper autour du code de Jim par Zoom Information, ce qui simplifie grandement cela:Licence
La solution d'Aviad est BSD.
La solution de Jim est du domaine public, tout comme son wrapper mentionné ci-dessus.
la source
AbstractIterator
.yield(i)
sera interrompu à partir du JDK 13, car ilyield
est ajouté en tant que nouvelle instruction Java / mot clé réservé.Ces deux approches peuvent être rendues un peu plus propres maintenant que Java a Lambdas. Vous pouvez faire quelque chose comme
J'ai expliqué un peu plus ici.
la source
Yielderable
? Ne devrait-il pas être justeYieldable
? (le verbe étant simplement 'yield', pas 'yielder' ou 'yielderate' ou autre)yield -> { ... }
sera interrompu à partir du JDK 13, car ilyield
est ajouté en tant que nouvelle instruction Java / mot-clé réservé.Je sais que c'est une question très ancienne ici, et il y a deux manières décrites ci-dessus:
yield
qui a évidemment des coûts de ressources.Cependant, il existe une autre façon, la troisième et probablement la plus naturelle, d'implémenter le
yield
générateur en Java qui est l'implémentation la plus proche de ce que font les compilateurs C # 2.0+ pour layield return/break
génération: lombok-pg . Il est entièrement basé sur une machine à états et nécessite une coopération étroite avecjavac
pour manipuler le code source AST. Malheureusement, le support lombok-pg semble être interrompu (aucune activité de référentiel pendant plus d'un an ou deux), et le projet original Lombok n'a malheureusement pas layield
fonctionnalité (il a un meilleur IDE comme Eclipse, support IntelliJ IDEA, cependant).la source
Stream.iterate (seed, seedOperator) .limit (n) .foreach (action) n'est pas le même que l'opérateur yield, mais il peut être utile d'écrire vos propres générateurs de cette façon:
la source
Je suggérerais également si vous utilisez déjà RXJava dans votre projet d'utiliser un Observable comme "yielder". Il peut être utilisé de la même manière si vous créez votre propre Observable.
Les observables peuvent être transformés en itérateurs afin que vous puissiez même les utiliser dans des boucles for plus traditionnelles. RXJava vous offre également des outils vraiment puissants, mais si vous n'avez besoin que de quelque chose de simple, ce serait peut-être exagéré.
la source
Je viens de publier une autre solution (sous licence MIT) ici , qui lance le producteur dans un thread séparé et met en place une file d'attente limitée entre le producteur et le consommateur, permettant la mise en mémoire tampon, le contrôle de flux et le pipelining parallèle entre le producteur et le consommateur (donc que le consommateur peut travailler à la consommation de l'article précédent pendant que le producteur travaille à la production de l'article suivant).
Vous pouvez utiliser ce formulaire de classe interne anonyme:
par exemple:
Ou vous pouvez utiliser la notation lambda pour réduire le passe-partout:
la source