The same pipeline — filter(even) → map(square) → take(n) — run two
ways over the same source. Array methods are eager: they walk
everything and allocate an array at each step. Iterator helpers are
lazy: they pull one element at a time and stop the moment
take(n) is full. The counters below are real — the
filter/map callbacks are instrumented, so you see exactly how many elements each
approach actually touched.
Both pipelines return the identical array. The difference is everything you
didn't see: the eager version visited the whole source and allocated a
fresh intermediate array after filter and again after map.
The lazy version threaded each element straight through and stopped early —
no wasted allocations, no wasted passes.