Unlike C#’s IEnumerable
, where an execution pipeline can be executed as many times as we want, in Java a stream can be ‘iterated’ only once.
Any call to a terminal operation closes the stream, rendering it unusable.
This ‘feature’ takes away a lot of power.
I imagine the reason for this is not technical. What were the design considerations behind this strange restriction?
Edit: in order to demonstrate what I am talking about, consider the following implementation of Quick-Sort in C#:
IEnumerable<int> QuickSort(IEnumerable<int> ints)
{
if (!ints.Any()) {
return Enumerable.Empty<int>();
}
int pivot = ints.First();
IEnumerable<int> lt = ints.Where(i => i < pivot);
IEnumerable<int> gt = ints.Where(i => i > pivot);
return QuickSort(lt).Concat(new int[] { pivot }).Concat(QuickSort(gt));
}
Now to be sure, I am not advocating that this is a good implementation of quick sort! It is however great example of the expressive power of lambda expression combined with stream operation.
And it can’t be done in Java!
I can’t even ask a stream whether it is empty without rendering it unusable.