Да, есть способ сделать это, но с некоторыми ограничениями.
Stream<Integer> infiniteStream = Stream.iterate( 0, x -> new Integer(x + 1) );
Iterator<Integer> iter = infiniteStream.iterator();
Integer zero = iter.next();
Integer one = iter.next();
Альтернативно,
Stream<Integer> infiniteStream = Stream.iterate( 0, x -> new Integer(x + 1) );
Spliterator<Integer> spliterator = infiniteStream.spliterator();
spliterator.tryAdvance(i -> System.out.println(i)); // zero
spliterator.tryAdvance(i -> System.out.println(i)); // one
Имея Stream
, можно получить из него Iterator
или Spliterator
, или запросить, является ли это параллельным потоком и т. д. Они определены в BaseStream
, суперинтерфейс Stream
, из-за чего их легко не заметить.
В этом случае мы знаем, что поток бесконечен, поэтому нет необходимости вызывать метод hasNext()
Итератора или проверять возвращаемое значение tryAdvance()
Разделителя.
Ограничение состоит в том, что оба метода iterator()
и spliterator()
Stream
являются терминальными операциями, что означает, что после их вызова возвращаемый Iterator или Spliterator имеет монопольный доступ к значениям, представленным Stream. Дальнейшие операции с потоком (такие как filter
или map
и т. д.) не разрешены и будут встречаться с IllegalStateException
.
Если вы хотите отделить первую пару элементов, а затем возобновить обработку потока, вы можете превратить разделитель обратно в поток следующим образом:
Stream<Integer> stream2 = StreamSupport.stream(spliterator, false);
Это, вероятно, будет хорошо работать для некоторых вещей, но я не уверен, что рекомендую эту технику в целом. Я думаю, что это добавляет несколько дополнительных объектов и, следовательно, дополнительные вызовы методов на пути создания следующего элемента.
Комментарии редакции (не относящиеся к вашему вопросу):
- Не используйте
new Integer(val)
. Вместо этого используйте Integer.valueOf(val)
, который будет повторно использовать упакованное целое число, если оно доступно, что обычно верно для значений в диапазоне от -128 до 127.
- Вы можете использовать
IntStream
вместо Stream<Integer>
, что полностью исключает накладные расходы на упаковку. У него нет полного набора потоковых операций, но есть iterate()
, который принимает функцию, работающую с примитивными значениями int
.
person
Stuart Marks
schedule
27.10.2014
.skip(n)
это способ сделать это. - person David Conrad   schedule 27.10.2014