1. ホーム
  2. java

[解決済み] IteratorをStreamに変換するには?

2022-03-18 01:32:07

質問

を簡潔に変換する方法を探しています。 Iterator Stream または、より具体的にはイテレータをストリームとして "view"することです。

パフォーマンス上の理由から、新しいリストにイテレータのコピーが入るのは避けたいところです。

Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Collection<String> copyList = new ArrayList<String>();
sourceIterator.forEachRemaining(copyList::add);
Stream<String> targetStream = copyList.stream();


コメントでいただいたご意見をもとに、私も 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);
}

しかし、私は NoSuchElementException (の呼び出しがないため)。 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)

を見てきました。 StreamSupport Collections が、何も見つかりませんでした。

解決方法は?

ひとつの方法として Spliterator から Iterator を作成し、それを元にストリームを作成します。

Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Stream<String> targetStream = StreamSupport.stream(
          Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED),
          false);

より可読性の高い代替案としては Iterable - を作成し Iterable から Iterator は、ラムダを使うと非常に簡単です。 Iterable は関数型インターフェイスです。

Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();

Iterable<String> iterable = () -> sourceIterator;
Stream<String> targetStream = StreamSupport.stream(iterable.spliterator(), false);