In order to get the full benefit from JDK 8 streams we will need to make them optimize fully. Here are a few thoughts about that.
I think of streams as a more concise and orderly replacement of classic "for" loops. Every stream can be rewritten as one or more for-loops, at the cost of verbosity and commitment to hard-coding optimizations (like FJ).
A classic "for" loop is a external iterator notation: The iteration machinery is outside of (lexically around) the data structure access. This notation is at least as old as Fortran. Streams are an internal iteration notation: The iteration machinery (crucially, the looping part of the algorithm) is inside the data structure, and only the loop body appears in the user code (as a lambda). This notation is also old, found in Lisp and Smalltalk.
External iterators are easier to optimize, because their crucial iteration logic is always