Busco una manera concisa para convertir una Iteratora una Streamo más específicamente a "ver" el iterador como una corriente.
Por razones de rendimiento, me gustaría evitar una copia del iterador en una nueva lista:
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Collection<String> copyList = new ArrayList<String>();
sourceIterator.forEachRemaining(copyList::add);
Stream<String> targetStream = copyList.stream();
Basado en algunas sugerencias en los comentarios, también he tratado de usar Stream.generate:
public static void main(String[] args) throws Exception {
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Stream<String> targetStream = Stream.generate(sourceIterator::next);
targetStream.forEach(System.out::println);
}
Sin embargo, obtengo un NoSuchElementException(ya que no hay invocación de hasNext)
Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractList$Itr.next(AbstractList.java:364)
at Main$$Lambda$1/1175962212.get(Unknown Source)
at java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef.tryAdvance(StreamSpliterators.java:1351)
at java.util.Spliterator.forEachRemaining(Spliterator.java:326)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at Main.main(Main.java:20)
Lo miré StreamSupporty Collectionsno encontré nada.

Stream.generate(iterator::next)funciona?Respuestas:
Una forma es crear un Spliterator desde el Iterator y usarlo como base para su transmisión:
Una alternativa que tal vez sea más legible es usar un Iterable, y crear un Iterable desde un Iterator es muy fácil con lambdas porque Iterable es una interfaz funcional:
fuente
sourceIterator.next()antes de usar la transmisión y verá el efecto (la transmisión no verá el primer elemento).Iterable<String> iterable = () -> sourceIterator;. Tengo que admitir que me tomó un tiempo entenderlo.Iterable<T>es unFunctionalInterfaceque solo tiene un método abstractoiterator(). Entonces, ¿() -> sourceIteratores una expresión lambda instanciando unaIterableinstancia como una implementación anónima?() -> sourceIterator;es una forma abreviada denew Iterable<>() { @Override public Iterator<String> iterator() { return sourceIterator; } }Desde la versión 21, la biblioteca Guava proporciona
Streams.stream(iterator)Se hace lo @ assylias 's respuesta espectáculos .
fuente
Gran sugerencia! Aquí está mi versión reutilizable:
Y uso (asegúrese de importar estáticamente asStream):
fuente
Esto es posible en Java 9.
fuente
.parallel()transmisiones. También parecen un poco más lentos que irSpliterator, incluso para uso secuencial.parallelpodría ser funky, la sencillez es increíble.La clase Create
SpliteratorfromIteratorusingSpliteratorscontiene más de una función para crear spliterator, por ejemplo, aquí estoy usandospliteratorUnknownSizeel iterador como parámetro, luego cree Stream usandoStreamSupportfuente
y uso
Streams.stream(iterator):fuente
Otra forma de hacer esto en Java 9+ usando Stream :: iterate (T, Predicate, UnaryOperator) :
fuente
Utilizar
Collections.list(iterator).stream()...fuente