【问题标题】:Java 8 Stream Closes when using map inside mapJava 8 Stream 在地图内使用地图时关闭
【发布时间】:2015-08-05 08:27:26
【问题描述】:

我正在尝试将两个流连接在一起。我遇到了我的流关闭的问题,我不明白为什么。没有人可以向我解释为什么会发生以下情况。

下面的代码不起作用。我在 flatMap 函数上收到流已关闭的异常。

private Stream<KeyValuePair<T, U>> joinStreams(Stream<T> first, Stream<U> second) {
        return 
                first
                    .map(x -> second
                                .map(y -> new KeyValuePair<T, U>(x, y))
                        )
                    .flatMap(x -> x);       
    }

当我首先从第二个流中收集一个列表,然后从该列表中获取一个流时,它确实有效。请参阅下面的示例。

private Stream<KeyValuePair<T, U>> joinStreams(Stream<T> first, Stream<U> second) {
    List<U> secondList = second.collect(Collectors.toList());
    return 
            first
                .map(x -> secondList.stream()
                            .map(y -> new KeyValuePair<T, U>(x, y))
                    )
                .flatMap(x -> x);       
}

我不明白为什么会这样。谁能解释一下?

编辑:

调用此函数的代码示例。

List<Integer> numbers1 = Arrays.asList(1, 2);
List<Integer> numbers2 = Arrays.asList(3, 4);

List<KeyValuePair<Integer, Integer>> combined = joinStreams(numbers1.stream(), numbers2.stream())
                                                    .collect(Collectors.toList());

// Expected result
// 1 3
// 1 4
// 2 3
// 2 4

【问题讨论】:

    标签: java java-8 java-stream


    【解决方案1】:

    问题是您的代码尝试处理第二个Stream 两次(第一个Stream 的每个元素一次)。 Stream 只能处理一次,就像 Iterator 只能遍历底层类的元素一次。

    如果您的第一个 Stream 只有一个元素,则代码可以工作,因为第二个 Stream 只会被处理一次。

    在有效的代码中,您为第一个Stream 的每个元素生成一个新的Stream(来自secondList),因此每个Stream 都被处理一次,无论有多少元素在第一个Stream

    【讨论】:

    • 我明白为什么它不起作用了,谢谢!你可能有一些关于我将如何解决这个问题的信息吗?每次都必须生成一个新列表似乎是浪费资源。
    • @Bob 您可以将 2 个列表(或集合)而不是两个流传递给您的方法。然后,您的方法将为第一个 List 创建一个 Stream,并为第二个 List 创建尽可能多的 Stream,并返回加入的 Stream。
    • @Bob,或者您可以不接受Stream&lt;U&gt;,而是接受Supplier&lt;Stream&lt;U&gt;&gt; 参数并使用supplier.get()。这样,您将不限于从集合创建的流,joinStreams(stream1, () -&gt; IntStream.range(0,100).boxed()) 之类的代码也可以使用。对于集合源,你需要写joinStreams(stream1, numbers2::stream)
    猜你喜欢
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 2016-12-27
    • 2023-03-14
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多