Java 8 是否缺少处理可变流的 Stream.concat ?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22743425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:38:15  来源:igfitidea点击:

Does Java 8 lack a Stream.concat working on a varags of streams?

javajava-8java-stream

提问by skiwi

Currently we have the following Stream.concatin Java 8:

目前我们Stream.concat在 Java 8 中有以下内容:

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

I am surprised as to why there is no version taking a varargs of Stream<? extends T>?

我很惊讶为什么没有采用可变参数的版本Stream<? extends T>

Currently I have code written like:

目前我写的代码如下:

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

If a varargs of this signature were available:

如果此签名的可变参数可用:

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

Then I could write it much more clearly as:

然后我可以把它写得更清楚:

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

Without all kinds of nested Stream.concatcalls.

没有各种嵌套Stream.concat调用。

Or are there other reasons why it is not provided?
I cannot think of such reasons, as we end up doing the job of a varargs call anyway now.

还是有其他原因没有提供?
我想不出这样的原因,因为我们现在无论如何都要完成 varargs 调用的工作。

回答by Boris the Spider

Just flatMapit:

flatMap这样:

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

In your example:

在你的例子中:

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

回答by assylias

Gleaned from a message in the thread linked by @RohitJain:

@RohitJain 链接的线程中的消息中收集

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

回答by radistao

SO, aggregating answers of.flatMap()vs of.reduce().orElseGet(): of.flatMapcan't process infinite streams, when of.reduce()- can. See the test example below:

所以,汇总.flatMap()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));
}
}

回答by Igor Rybak

In Google Guava v21.0+ there is:

在 Google Guava v21.0+ 中有:

com.google.common.collect.Streams#concatmethod

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