このページはまだ翻訳されていないため、英語で表示されます。 翻訳に参加する

toList

Materializes a lazy iterable — pulling every value and collecting them into a List.

List<A> toList<A>(Iterable<A> iterable) Future<List<A>> toListAsync<A>(FxAsyncIterable<A> iterable) List<T> Fx.toList() // chain Future<List<T>> FxAsync.toList()

Lecture

toList is the workhorse terminal operator: it's what actually runs a chain that was, until this point, nothing but a plan. Calling .toList() pulls every remaining value out of the iterable, in order, and collects them into a real List<T>. Everything upstream — every .map(), .filter(), .take() — only runs because toList asked for values.

That also means toList is exactly the operator you must not call directly on an infinite or unbounded source (range with no end, cycle, repeat with a huge count) — it will try to pull forever. Bound it first with take(n), then call toList on the bounded result.

The async version, toListAsync (or .toList() on an FxAsync chain), awaits each element as it's pulled and returns a Future<List<T>>. Combined with .concurrent(n) upstream, the individual awaits can overlap even though the final list still comes back in the original order.

Demo 1 · Basics & laziness

Note how map only actually runs for the 3 values that take(3) allows through — out of a million:

Demo 2 · Async, with concurrency

.toList() on an FxAsync chain awaits every element and hands back the whole list at once; add .concurrent(n) upstream to overlap the individual waits:

Try it yourself

Exercise: materialize the first 4 squares of a huge range into a List.

Related: each — terminal op for side effects instead of a List · consume — terminal op that discards results entirely · fx — the chain that toList terminates · concurrent — parallel evaluation