web-dev-qa-db-ja.com

Java 8には、さまざまなストリームで動作するStream.concatがありませんか?

現在、Java 8には次のStream.concatがあります。

public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b);

なぜStream<? extends T>の可変引数を取るバージョンがないのかと驚いています。

現在、私は次のように書かれたコードを持っています:

Stream<Integer> resultStream = Stream.concat(stream1, Stream.concat(stream2, Stream.of(element)))
        .filter(x -> x != 0)
        .filter(x -> x != 1)
        .filter(x -> x != 2);

この署名の可変引数が利用可能である場合:

public static <T> Stream<T> concat(Stream<? extends T>... streams);

それから私はそれをはるかに明確に書くことができます:

Stream<Integer> resultStream = Stream.concat(
                stream1,
                stream2,
                Stream.of(element)
        )
        .filter(x -> x != 0)
        .filter(x -> x != 1)
        .filter(x -> x != 2);

すべての種類のネストされたStream.concat呼び出しなし。

それとも提供されない理由は他にありますか?
結局のところ、varargs呼び出しの仕事をすることになるので、そのような理由は考えられません。

49
skiwi

ただflatMap it:

public static void main(final String[] args) throws Exception {
    final Stream<String> stream1 = /*some stream*/
    final Stream<String> stream2 = /*some stream*/
    final Stream<String> stream3 = /*some stream*/
    final Stream<String> stream4 = /*some stream*/
    final Stream<String> stream5 = /*some stream*/

    final Stream<String> stream = Stream.of(stream1, stream2, stream3, stream4, stream5).flatMap(Function.identity());
}

あなたの例では:

Stream<Integer> resultStream = Stream.of(stream1, stream2, Stream.of(element))
        .flatMap(identity())
        .filter(x -> x != 0)
        .filter(x -> x != 1)
        .filter(x -> x != 2);
49

@ RohitJainによってリンクされたスレッド内のメッセージ から収集された:

Stream.of(s1, s2, s3, ...)
  /* .parallel() if you want*/
  .reduce(Stream::concat)
  .orElseGet(Stream::empty);
33
assylias

Google Guava v21.0 +には次のものがあります。

com.google.common.collect.Streams#concat 方法

5
Igor Rybak

SO、回答の集計 of.flatMap() vs of.reduce()。orElseGet() :_of.flatMap_は、of.reduce() - できる。以下のテスト例をご覧ください。

_@RunWith(JUnit4.class)
public class StreamConcatTest {

@Rule
public Timeout globalTimeout = Timeout.seconds(3);

private static final Random randomSupplier = new Random(System.currentTimeMillis());

private Stream<Stream<Integer>> mergedStream;

@Before
public void setUp() throws Exception {
    Stream<Integer> infinite = Stream.concat(
            Stream.of(1, 2, 3, 4, 5),
            Stream.generate(randomSupplier::nextInt)
    );

    Stream<Integer> finite1 = Stream.of(100, 101, 102, 103);
    Stream<Integer> finite2 = Stream.of(222, 333, 444, 555);

    mergedStream = Stream.of(infinite, finite1, finite2);
}

@Test
public void of_flatMap_FAILS_BY_TIMEOUT() throws Exception {
    Stream<Integer> streamToTest = mergedStream
            .flatMap(i -> i);

    assertThat(streamToTest
                    .skip(3)
                    .findFirst() // this should break infinite stream, but can't
                    .orElse(-1),
            is(4));
}

@Test
public void of_reduce_SUCCESS() throws Exception {
    Stream<Integer> streamToTest = mergedStream
            .reduce(Stream::concat)
            .orElseGet(Stream::empty);

    assertThat(streamToTest
                    .skip(3)
                    .findFirst() // this really breaks infinite stream
                    .orElse(-1),
            is(4));
}
}
_
1
radistao