bugfix> java > 投稿

未定義の長さのJavaストリームがあります。次に、データベースからいくつかのメタデータをロードし、それをストリーミングデータに割り当てる必要があります。

私はできない:

  • ストリームからすべてのデータを一度にRAMにロードし、メタデータを入力してから、大量のRAMを使用する可能性があるため新しいストリームを開始する
  • 各要素のメタデータを個別にロードします。これにより、データベースに大量のリクエストが溢れます。

したがって、データベースのパーティションにメタデータをロードできると考えました。

このようなメソッドが必要です:

<T> Stream<List<T>> partition(Stream<T> stream, int partitionSize)

だから私はこのように使うことができます

partition(dataSource.stream(), 1000)
    .map(metadataSource::populate)
    .flatMap(List::stream)
    .forEach(this::doSomething);

もう見つけたGuava's Iteralbes#partition しかし、その場合、ストリームを反復可能に変換し、パーティションを作成し、再度ストリームに変換する必要があります。ストリームパーティショニングに組み込まれているものはありますか、それとも自分で実装する簡単な方法はありますか?

回答 1 件
  • これを行う既存のメソッドはまだ見つかっていないので、自分で実装しました。

    public class Partitioner<E> implements Iterator<List<E>> {
        private final Iterator<E> iterator;
        private final int partitionSize;
        public static <T> Stream<List<T>> partition(final Stream<T> stream, final int partitionSize) {
            return new Partitioner<>(stream, partitionSize).asStream();
        }
        public Partitioner(final Stream<E> stream, final int partitionSize) {
            this(stream.iterator(), partitionSize);
        }
        public Partitioner(final Iterator<E> iterator, final int partitionSize) {
            this.iterator = iterator;
            this.partitionSize = partitionSize;
        }
        @Override
        public boolean hasNext() {
            return this.iterator.hasNext();
        }
        @Override
        public List<E> next() {
            if (!hasNext()) {
                throw new NoSuchElementException("No more elements");
            }
            final ArrayList<E> result = new ArrayList<>(this.partitionSize);
            for (int i = 0; i < this.partitionSize && hasNext(); i++) {
                result.add(this.iterator.next());
            }
            return result;
        }
        public Stream<List<E>> asStream() {
            return StreamSupport.stream(Spliterators.spliteratorUnknownSize(this, Spliterator.NONNULL), false);
        }
    }
    
    

あなたの答え