私は見ていたこの怠惰なストリームの建設のためのリンクと私の例1のためにそれを使用してみました。
私の主な流れが必要とされている一部の操作は、上で行う必要がありStream.onClose() 。
私のカスタムロジックでは、私はからIteratorを使用しStream.iterator()ストリーム処理のために。
これは、実際のストリームを消費罰金を働きました。私が使用した場合でも、Stream.flatMapを()怠惰なストリームを構築するために、onClose
私はターン私のための問題を作成する、反復処理を開始すると、関数が呼び出されます。
私は、両方の環境では、この例外に直面していますズールー-opendjk 1.8.0_222および13でこれを試してみました。
You can reproduce the problem with the below code.
import java.util.*;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class TestStreamIterator
{
public static void main(String args[])
{
Stream<String> stream1 = getStream();
stream1.iterator().forEachRemaining(System.out::println);
Stream<String> stream2 = Stream.of(1).flatMap(integer -> getStream());
stream2.iterator().forEachRemaining(System.out::println);
}
private static Stream<String> getStream()
{
List<String> values = Arrays.asList("a", "b", "c");
MyIterator iterator = new MyIterator(values);
Stream<String> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.NONNULL | Spliterator.IMMUTABLE), false).onClose(iterator::close);
return stream;
}
private static class MyIterator implements Iterator<String>, AutoCloseable
{
private Iterator<String> iterator;
public MyIterator(List<String> values)
{
iterator = values.iterator();
}
@Override
public boolean hasNext()
{
return iterator.hasNext();
}
@Override
public String next()
{
return iterator.next();
}
@Override
public void close()
{
throw new IllegalStateException("Should not come here");
}
}
}
My understating is, when using flatMap
; close
method of Stream.of(1)
only should be called. Not of the stream created inside flatMap
function.
I was expecting the onClose
function to be invoked only when the stream is closed. But, I am not sure where the stream is getting closed.
Any help on solving this case would also be helpful.
When you call flatMap(integer -> getStream())
here:
Stream<String> stream2 = Stream.of(1).flatMap(integer -> getStream());
stream2.iterator().forEachRemaining(System.out::println);
You are calling this method:
Iterator
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream. (If a mapped stream is null an empty stream is used, instead.)
So as the documentation says, the mapped stream you pass into this method (from getStream()
which is a Stream over a MyIterator
) will be closed, which it is, then (as defined in onClose
of that Stream) it calls MyIterator.close()
which throws the exception.
Addressing your comment since you don't seem to follow:
Stream<String> stream2 = Stream.of(1).flatMap(integer -> getStream());
あなたがそれを読んだときに遅延したサブストリームの内容にマップするストリームを作成します。そのサブストリームをメインストリームにロードされると、サブストリームが閉じられます。
stream2.iterator().forEachRemaining(System.out::println);
その後、通話サブストリーム閉じ、すべてのサブストリームを読み込み、サブストリームにマップのメインストリーム、から読み取るStream.onClose()
呼び出しをMyIterator.close()