本页尚未翻译,因此以英文显示。 参与翻译

cycle

Yields a sequence, then repeats it — forever. Always pair it with a bound like take.

Iterable<T> cycle<T>(Iterable<T> iterable) FxAsyncIterable<T> cycleAsync<T>(FxAsyncIterable<T> iterable) Fx<T> Fx.cycle() // chain FxAsync<T> FxAsync.cycle()

Lecture

cycle is infinite: it plays the source sequence once, buffering its values as it goes, then loops over that buffer forever. Unlike everything else in this section, cycle never runs out on its own — you must always pair it with something that decides when to stop, almost always .take(n). Calling toList() or consume() directly on a bare cycle(...) without a bound in between will hang.

One edge case worth knowing: cycling an empty source yields nothing at all, rather than looping forever over zero elements — so cycle([]) is safe and simply produces an empty result.

It's a natural building block for round-robin assignment (cycle through a small list of workers/colors/slots as you map over a longer one) or for repeating a short async sequence to model a polling loop. The async form, cycleAsync (or .cycle() on an FxAsync chain), buffers and loops the same way, but pulls each round through the usual async protocol.

Demo 1 · Infinite, bounded by take

Demo 2 · Async cycle, still bounded by take

Try it yourself

Exercise: cycle through traffic-light colors and take the first 8.

Related: range — a finite counting sequence · repeat — repeat a single value, a fixed number of times · take — the bound cycle almost always needs · concurrent — overlap an async cycle's work