3

私はすべての私の研究に少し混乱しています。私は TabularResultSet という名前のカスタム インターフェイスを持っています (例のために骨抜きにしました)。これは、本質的に表形式のデータ セットを通過します。イテレータのような next() メソッドがあり、QueryResultSet、クリップボードからのタブ付きテーブル、CSV などをループできます。

ただし、 TabularResultSet をラップして簡単にストリームに変換する Spliterator を作成しようとしています。TabularResultSet が QueryResultSet をトラバースしている可能性があり、同時に next() を呼び出すと大混乱が生じる可能性があるため、並列化する安全な方法を想像できません。並列化を安全に行うことができる唯一の方法は、next() を単一の作業スレッドから呼び出し、データを並列スレッドに渡して処理することです。

したがって、並列化は簡単なオプションではないと思います。これを並列化せずにストリーミングするにはどうすればよいですか? これが私のこれまでの仕事です...

public final class SpliteratorTest {

    public static void main(String[] args) {
       TabularResultSet rs = null; /* instantiate an implementation; */

       Stream<TabularResultSet> rsStream = StreamSupport.stream(new TabularSpliterator(rs), false);
    }

    public static interface TabularResultSet {
        public boolean next();

        public List<Object> getData();
    }

    private static final class TabularSpliterator implements Spliterator<TabularResultSet> {

        private final TabularResultSet rs;

        public TabularSpliterator(TabularResultSet rs) {
            this.rs = rs;
        }
        @Override
        public boolean tryAdvance(Consumer<? super TabularResultSet> action) {
            action.accept(rs);
            return rs.next();
        }

        @Override
        public Spliterator<TabularResultSet> trySplit() {
            return null;
        }

        @Override
        public long estimateSize() {
            return Long.MAX_VALUE;
        }

        @Override
        public int characteristics() {
            return 0;
        }
    }
}
4

2 に答える 2

5

拡張するのがおそらく最も簡単Spliterators.AbstractSpliteratorです。これを行う場合は、実装するだけで済みますtryAdvance。これは並列ストリームに変換できます。並列処理は、ストリームの実装が複数回呼び出しtryAdvance、受信したデータをバッチ処理し、異なるスレッドで処理することによって実現されます。

TabularResultSetJDBC のようなものがあれば、または はResultSet必要ないと思います。代わりに、 は表形式のデータ セット全体を表しているように見えるため、各スプリッテレータまたはストリーム要素でそのテーブルの 1 つの行を表す必要があります。これは?によって返されます。もしそうなら、あなたは次のようなものが欲しいでしょう。Spliterator<TabularResultSet>Stream<TabularResultSet>TabularResultSetList<Object>getData()

class TabularSpliterator extends Spliterators.AbstractSpliterator<List<Object>> {
    private final TabularResultSet rs;

    public TabularSpliterator(TabularResultSet rs) {
        super(...);
        this.rs = rs;
    }

    @Override public boolean tryAdvance(Consumer<? super List<Object>> action) {
        if (rs.next()) {
            action.accept(rs.getData());
            return true;
        } else {
            return false;
        }
    }
}

次に、 を呼び出して、このスプリッテレータのインスタンスをストリームに変換できますStreamSupport.stream()

注: 一般に、Spliterator インスタンスは複数のスレッドから呼び出されることはなく、スレッドセーフである必要さえありません。詳細については、Spliterator クラスのドキュメントの「にもかかわらず...」で始まる段落を参照してください。

于 2015-03-09T05:14:17.647 に答える