Невозможно перебрать поток, созданный (второй раз) с помощью 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 учебный класс:

Поток должен использоваться (вызывая промежуточную или терминальную операцию потока) только один раз. Это исключает, например, "разветвленные" потоки, где один и тот же источник передает два или более конвейеров, или несколько обходов одного и того же потока.

Другие вопросы по тегам