toList

지연 이터러블을 구체화합니다 — 모든 값을 끌어당겨 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()

강의

toList는 가장 많이 쓰이는 종결 연산자입니다. 그 시점까지 계획에 불과했던 체인을 실제로 실행시키는 것이 바로 이 함수입니다. .toList()를 호출하면 이터러블에 남아 있는 모든 값을 순서대로 끌어당겨 진짜 List<T>에 담습니다. 상류의 모든 것 — .map(), .filter(), .take() — 은 toList가 값을 요청했기 때문에 비로소 실행됩니다.

뒤집어 말하면 toList는 무한하거나 크기가 정해지지 않은 소스에 직접 호출해서는 안 되는 연산자이기도 합니다(끝이 없는 range, cycle, 개수가 아주 큰 repeat). 영원히 값을 끌어당기려 들기 때문입니다. 먼저 take(n)으로 범위를 한정한 다음, 그 결과에 toList를 호출하세요.

비동기 버전인 toListAsync(또는 FxAsync 체인에서의 .toList())는 원소를 끌어당길 때마다 await하며 Future<List<T>>를 반환합니다. 상류에 .concurrent(n)을 함께 쓰면 개별 await가 겹쳐 실행되지만, 최종 리스트는 여전히 원래 순서대로 돌아옵니다.

데모 1 · 기본과 지연 평가

백만 개 중에서 take(3)이 통과시킨 3개에 대해서만 map이 실제로 실행되는 것을 확인해 보세요.

데모 2 · 비동기, 그리고 동시성

FxAsync 체인에서의 .toList()는 모든 원소를 await한 뒤 리스트 전체를 한 번에 돌려줍니다. 상류에 .concurrent(n)을 추가하면 개별 대기 시간이 서로 겹칩니다.

직접 해 보기

연습: 아주 큰 범위에서 앞쪽 4개의 제곱을 List로 구체화해 보세요.

관련 항목: each — List 대신 부수 효과를 위한 종결 연산자 · consume — 결과를 아예 버리는 종결 연산자 · fx — toList가 종결시키는 그 체인 · concurrent — 병렬 평가