Hi everyone, I just discovered a weird discrepancy for Iterator between scala 2.12 and 2.13. And wondering to know if this is a bug of 2.12, or a behavior change in 2.13?
scala> val it = Iterator(1,2,3)
val it: Iterator[Int] = <iterator>
scala> it.take(1).toList
val res14: List[Int] = List(1)
scala> it.take(1).toList
val res15: List[Int] = List(2)
scala> it.take(1).toList
val res16: List[Int] = List(3)
As you can see, in 2.12, the underlying state is not shared between source and derivative iterators. So take() does not move current element forward, while in 2.13 the opposite is true.
So is this expected in 2.12 that derived iterator not sharing state with parent iterator, or is this a bug?
Reuse: After calling this method, one should discard the iterator it was called on, and use only the iterator that was returned. Using the old iterator is undefined, subject to change, and may result in changes to the new iterator as well.
Hi, thanks for replying. I do assume .take() or other method will change its state. So I thought 2.13’s behavior was what I expected. i.e., calling .take() will change its current element.
I get your point that mutation is not guaranteed. If so, I have another question:
How to easily iterate an iterator one batch of elements at a time? For example, I wanna take the first 10 elements from iterator, then the next 10 elements, until it’s exhausted. I thought .take() would do that. It seems it’s not guaranteed.
It is of particular importance to note that, unless stated otherwise, one should never use an iterator after calling a method on it . The two most important exceptions are also the sole abstract methods: next and hasNext .
Behavior when reusing such an Iterator is undefined.
So basically when working with iterators you can either use the high-level API in a pipeline fashion without reusing intermediary iterators (e.g. it.map(...).take(...).filter(...).drop(...).toList). Or you can implement some custom low-level logic with next and hasNext.
But be careful with using splitAt in a loop or a recursive function. Last time I tried, this created long chains of iterators that blew in my face on large iterations.