В отличие от С# IEnumerable
, где конвейер выполнения может выполняться столько раз, сколько мы хотим, в Java поток может быть "итерирован" только один раз.
Любой вызов операции терминала закрывает поток, что делает его непригодным. Эта "особенность" отнимает много энергии.
Я предполагаю, что причина этого не техническая. Каковы были соображения дизайна за этим странным ограничением?
Изменить: чтобы продемонстрировать, о чем я говорю, рассмотрим следующую реализацию Quick-Sort в С#:
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));
}
Теперь, конечно, я не сторонник того, что это хорошая реализация быстрой сортировки! Это, однако, отличный пример выразительной способности лямбда-выражения в сочетании с работой потока.
И это невозможно сделать на Java! Я даже не могу спросить поток, пустой ли он, не делая его непригодным.