Javaの怠惰なストリーム建設中の問題

suraj1291993:

私は見ていたこの怠惰なストリームの建設のためのリンクと私の例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.

xtratic :

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()

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=313179&siteId=1