What you're doing in the initial for
loop is to build a very big object tree describing what you want to achieve.
There will be a Stream
implementation that knows that it wants to do a flatMap
on two values, one of which will be a Stream
implementation that knows that it wants to do a flatMap
on two values, one of which will be a Stream
implementation that knows that it wants to do a flatMap
on two values, one of which will be a Stream
implementation that knows that it wants to do a flatMap
on two values, one of which will be a Stream
implementation that knows that it wants to do a flatMap
on two values, one of which will be a Stream
implementation that knows that it wants to do a flatMap
on two values, one of which will be a Stream
implementation that knows that it wants to do a flatMap
on two values, ... , one of which is an empty Stream
implementation.
Internally those are implemented as wrapper around each other and by calling each other when necessary.
Since each Stream
implementation needs to call the next one and that chain is many thousands of objects deep, you'll need at least such a deep stack to be able to fully execute it (in practice probably a multiple of that number, since there might be some helper/intermediary methods on the stack as well).
In your working code you only have one Stream
that holds a list of Stream
objects to iterate over. So the call depths is very limited: the outer stream delegates to the inner ones one-after-another.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…