Jak przekonwertować iterator na strumień?
Szukam zwięzłego sposobu na konwersję Iterator
do a Stream
a dokładniej do "oglądania" iteratora jako strumienia.
Ze względu na wydajność, chciałbym uniknąć kopii iteratora na nowej liście:
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Collection<String> copyList = new ArrayList<String>();
sourceIterator.forEachRemaining(copyList::add);
Stream<String> targetStream = copyList.stream();
Bazując na kilku sugestiach w komentarzach, starałem się również wykorzystać 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);
}
Jednak dostaję NoSuchElementException
(ponieważ nie ma wywołania 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)
Mam spojrzał na StreamSupport
oraz Collections
ale nic nie znalazłem.
8 answers
Jednym ze sposobów jest utworzenie Spliterator
z Iterator
i użycie go jako podstawy dla strumienia:
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Stream<String> targetStream = StreamSupport.stream(
Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED),
false);
Alternatywą, która może być bardziej czytelna, jest użycie Iterable
- A tworzenie Iterable
z Iterator
jest bardzo łatwe z lambda, ponieważ Iterable
jest funkcjonalnym interfejsem:
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Iterable<String> iterable = () -> sourceIterator;
Stream<String> targetStream = StreamSupport.stream(iterable.spliterator(), false);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-25 09:02:31
Od wersji 21 Biblioteka Guava udostępnia Streams.stream(iterator)
Robi to, co @ ' S odpowiedź pokazuje .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-29 16:03:47
Świetna sugestia! Oto moje podejście do tego wielokrotnego użytku:
public class StreamUtils {
public static <T> Stream<T> asStream(Iterator<T> sourceIterator) {
return asStream(sourceIterator, false);
}
public static <T> Stream<T> asStream(Iterator<T> sourceIterator, boolean parallel) {
Iterable<T> iterable = () -> sourceIterator;
return StreamSupport.stream(iterable.spliterator(), parallel);
}
}
I użycie (upewnij się, że statycznie zaimportujesz asStream):
List<String> aPrefixedStrings = asStream(sourceIterator)
.filter(t -> t.startsWith("A"))
.collect(toList());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-23 21:16:53
Jest to możliwe w Javie 9.
Stream.generate(() -> null)
.takeWhile(x -> iterator.hasNext())
.map(n -> iterator.next())
.forEach(System.out::println);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-12 19:45:23
Create Spliterator
from Iterator
using Spliterators
class contains more than one function for creating spliterator, for example here am using spliteratorUnknownSize
which is getting iterator as parameter, then create Stream using StreamSupport
Spliterator<Model> spliterator = Spliterators.spliteratorUnknownSize(
iterator, Spliterator.NONNULL);
Stream<Model> stream = StreamSupport.stream(spliterator, false);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-11 12:18:43
import com.google.common.collect.Streams;
I użycie Streams.stream(iterator)
:
Streams.stream(iterator)
.map(v-> function(v))
.collect(Collectors.toList());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-09 06:01:30
Inny sposób na to w Javie 9 + za pomocą Stream::iterate(T, Predicate, UnaryOperator)
:
Stream.iterate(iterator, Iterator::hasNext, UnaryOperator.identity())
.map(Iterator::next)
.forEach(System.out::println);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-25 09:02:49
Użyj Collections.list(iterator).stream()...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-30 15:24:45