Невозможно перебрать поток, созданный (второй раз) с помощью Steam.spliterator на Iterable
Я не могу перебрать (второй раз) поток, созданный с помощью Steam.spliterator. Я не мог найти документацию о том же.
Вот что я делаю:
Я получил Iterable
как аргумент funciton, и я повторяю это через поток, как следующий код:
StreamSupport.stream(values.spliterator(), false)
и после этого я делаю это снова, но второй не повторяется вообще. Я потратил много времени на его отладку и, наконец, преобразовал итерируемое в список в самом начале.
Кто-нибудь из вас, ребята, знает причину?
Изменить: Извините, если я не ясно,
Я не использовал поток несколько раз, я генерировал поток вышеупомянутым способом с тем же итерируемым.
Итерируемый - это тот, который идет от сокращения в работе MapReduce.
Спасибо, Хариндра
2 ответа
Будьте уверены, что Iterable
экземпляр, который вы используете для создания вашего Spliterator
действительно чтит Iterable
контракт. Некоторые люди делают ошибку, думая, что все, что реализует iterator()
будет служить Iterable
и это не тот случай. Соблюдать Iterable
контракт, надо уметь звонить iterator()
несколько раз и иметь возможность повторять с ним каждый раз.
Потому что очень легко создать Iterable
от всего, что имеет iterator()
Я видел несколько случаев Iterable
демонстрируя поведение, которое вы упоминаете. Например, можно сделать это:
Stream<String> stream = ...
Iterable<String> falseIterable = stream::iterator;
falseIterable
не следует обязательным Iterable
семантика, потому что falseIterable.iterator()
, будучи оберткой вокруг stream.iterator()
, не вернет юзабилити Iterator
во второй раз, после того, как это было повторено.
Stream
это одноразовый объект. Вы можете потреблять его только один раз, а не несколько раз. Если вы хотите использовать содержимое несколько раз, вы должны делать то же, что и вы, конвертируя поток в список или массив или что-то не потоковое, а затем создавая из него два новых потока для двух вещей, которые вы хотите сделать.
Цитата из JavaDoc изStream
учебный класс:
Поток должен использоваться (вызывая промежуточную или терминальную операцию потока) только один раз. Это исключает, например, "разветвленные" потоки, где один и тот же источник передает два или более конвейеров, или несколько обходов одного и того же потока.