Existe-t-il un moyen simple de créer un flux infini à l’aide de Java-8 sans bibliothèques externes?
Par exemple en Scala:
Iterator.iterate(0)(_ + 2)
Oui, il existe un chemin facile :
IntStream.iterate(0, i -> i + 2);
Avec comme cas d'utilisation:
IntStream.iterate(0, i -> i + 2)
.limit(100)
.forEach(System.out::println);
Qui imprime 0 à 198 en augmentant par pas de 2.
La méthode générique est:
Stream.iterate(T seed, UnaryOperator<T> f);
Ce dernier peut être plus rare dans l'utilisation.
Voici un exemple:
PrimitiveIterator.OfInt it = new PrimitiveIterator.OfInt() {
private int value = 0;
@Override
public int nextInt() {
return value++;
}
@Override
public boolean hasNext() {
return true;
}
};
Spliterator.OfInt spliterator = Spliterators.spliteratorUnknownSize(it,
Spliterator.DISTINCT | Spliterator.IMMUTABLE |
Spliterator.ORDERED | Spliterator.SORTED);
IntStream stream = StreamSupport.intStream(spliterator, false);
C'est un peu verbeux, comme vous le voyez. Pour imprimer les 10 premiers éléments de ce flux:
stream.limit(10).forEach(System.out::println);
Vous pouvez bien sûr aussi transformer les éléments, comme vous le faites dans votre exemple Scala:
IntStream plusTwoStream = stream.map(n -> n + 2);
Notez qu'il existe des flux infinis intégrés tels que Java.util.Random.ints()
qui vous donne un flux infini d'entiers aléatoires.
Il existe une autre solution possible dans Java 8:
AtomicInteger adder = new AtomicInteger();
IntStream stream = IntStream.generate(() -> adder.getAndAdd(2));
Important: un ordre de nombres n'est conservé que si le flux est séquentiel.
Il faut également noter qu'une nouvelle version du IntStream.iterate
a été ajoutée depuis Java 9:
static IntStream iterate(int seed,
IntPredicate hasNext,
IntUnaryOperator next);
Exemples:
IntStream stream = IntStream.iterate(0, i -> i >= 0, i -> i + 2);
IntStream.iterate(0, i -> i < 10, i -> i + 2).forEach(System.out::println);
Vous pouvez construire votre propre InfiniteStream en implémentant stream et consumer et en composer les deux. Vous aurez peut-être besoin d'une file d'attente pour mettre vos données en file d'attente:
public class InfiniteStream<T> implements Consumer<T>, Stream<T> {
private final Stream<T> stream;
private final Queueing q;
...
public InfiniteStream(int length) {
this.q = new Queueing(this.length);
this.stream = Stream.generate(q);
...
}
//implement stream methods
//implement accept
}
vérifier le code complet ici https://Gist.github.com/bassemZohdy/e5fdd56de44cea3cd8ff