在地图内

时间:2015-08-05 08:27:27

标签: java java-8 java-stream

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

以下代码不起作用。我在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

1 个答案:

答案 0 :(得分:5)

问题是您的代码尝试处理第二个Stream两次(对于第一个Stream的每个元素一次)。 Stream只能处理一次,就像Iterator只能迭代基础类的元素一样。

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

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