Existe-t-il un équivalent Java du mot-clé ‘yield’ de C #?

Je sais qu’il n’y a pas d’équivalent direct en Java même, mais peut-être un tiers?

C’est vraiment pratique. Actuellement, je voudrais implémenter un iterator qui fournit tous les nœuds d’un arbre, soit environ cinq lignes de code avec rendement.

Les deux options que je connais sont la bibliothèque de collections d’informations financières 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 yield return construction similaire à un yield return en Java, de sorte que les deux satisferont votre requête. Les différences notables entre les deux sont:

Mécanique

La bibliothèque d’Aviad utilise la manipulation de bytecode alors que Jim utilise le multithreading. Selon 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 possède une interface plus propre – voici un exemple:

 Iterable it = new Yielder() { @Override protected void yieldNextCore() { for (int i = 0; i < 10; i++) { yieldReturn(i); if (i == 5) yieldBreak(); } } }; 

Bien que Jim soit beaucoup plus compliqué, vous devez adept un Collector générique qui a une méthode de collect(ResultHandler) ... ugh. Cependant, vous pouvez utiliser quelque chose comme cette enveloppe autour du code de Jim par Zoom Information, ce qui simplifie grandement:

 Iterable it = new Generator() { @Override protected void run() { for (int i = 0; i < 10; i++) { yield(i); if (i == 5) return; } } }; 

Licence

La solution d'Aviad est BSD.

La solution de Jim est du domaine public, de même que son emballage mentionné ci-dessus.

Voici un article sur ceci et la bibliothèque de Jim Blackler qui fait cela en Java seul.

Ces deux approches peuvent être un peu plus claires maintenant que Java a Lambdas. Vous pouvez faire quelque chose comme

 public Yielderable oneToFive() { return yield -> { for (int i = 1; i < 10; i++) { if (i == 6) yield.breaking(); yield.returning(i); } }; } 

J'ai expliqué un peu plus ici.

Je sais que c’est une très vieille question ici, et il y a deux manières décrites ci-dessus:

  • la manipulation de bytecode n’est pas si facile lors du portage;
  • le yield basé sur le thread qui a évidemment des coûts de ressources.

Cependant, il existe un autre moyen, le troisième et probablement le plus naturel, d’implémenter le générateur de yield en Java qui est le plus proche de ce que font les compilateurs C # 2.0+ pour la génération de yield return/break : lombok-pg . Il est entièrement basé sur une machine à états et nécessite une coopération étroite avec javac pour manipuler le code source AST. Malheureusement, le support de lombok-pg semble être interrompu (pas d’activité de repository depuis plus d’un an ou deux), et le projet original Lombok manque malheureusement de la fonctionnalité de yield (il a un meilleur IDE comme Eclipse, support d’IntelliJ IDEA).

Stream.iterate (seed, seedOperator) .limit (n) .foreach (action) est différent de l’opérateur de production, mais il peut être utile d’écrire vos propres générateurs de cette façon:

 import java.util.stream.Stream; public class Test01 { private static void myFoo(int someVar){ //do some work System.out.println(someVar); } private static void myFoo2(){ //do some work System.out.println("some work"); } public static void main(Ssortingng[] args) { Stream.iterate(1, x -> x + 1).limit(15).forEach(Test01::myFoo); //var1 Stream.iterate(1, x -> x + 1).limit(10).forEach(item -> myFoo2()); //var2 } } 

Dans Java 8, vous pouvez utiliser: Stream.of