当在映射内部使用映射时,Java8流关闭

当在映射内部使用映射时,Java8流关闭,java,java-8,java-stream,Java,Java 8,Java Stream,我正试图把两条小溪连接在一起。我遇到了我的流关闭的问题,我不明白为什么。谁也不能向我解释一下为什么会发生以下情况 下面的代码不起作用。我在flatMap函数中得到一个异常,流已经关闭。 private Stream<KeyValuePair<T, U>> joinStreams(Stream<T> first, Stream<U> second) { return first

我正试图把两条小溪连接在一起。我遇到了我的流关闭的问题,我不明白为什么。谁也不能向我解释一下为什么会发生以下情况

下面的代码不起作用。我在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);       
    }
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
私有流joinStreams(流第一,流第二){
返回
第一
.map(x->second
.map(y->新键值对(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);       
}
私有流joinStreams(流第一,流第二){
List secondList=second.collect(Collectors.toList());
返回
第一
.map(x->secondList.stream()
.map(y->新键值对(x,y))
)
.flatMap(x->x);
}
我不明白为什么会这样。有人能解释一下吗

编辑:

调用此函数的代码示例。

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);       
    }
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
List numbers1=Arrays.asList(1,2);
List numbers2=Arrays.asList(3,4);
列表组合=joinStreams(numbers1.stream(),numbers2.stream())
.collect(Collectors.toList());
//预期结果
// 1 3
// 1 4
// 2 3
// 2 4

问题在于,您的代码尝试处理第二个
流两次(第一个
流的每个元素一次)。
只能处理一次,就像
迭代器
只能在底层类的元素上迭代一次一样

如果第一个
只有一个元素,那么代码就可以工作,因为第二个
只能处理一次


在有效的代码中,您为第一个
的每个元素生成一个新的
(从
第二个列表
),因此每个
都会处理一次,而不管第一个
流中有多少元素
,我理解为什么它不起作用,谢谢!你可能知道我将如何解决这个问题吗?每次都必须生成一个新列表似乎是浪费资源。@Bob您可以将列表(或集合)传递给方法2,而不是两个流。然后,您的方法将为第一个列表创建一个流,为第二个列表创建所需数量的流,并返回连接的流。@Bob,或者您可以不接受
,而接受
供应商
参数,并使用
供应商.get()
。这样,您就不局限于从集合创建的流,类似于
joinStreams(stream1,()->IntStream.range(0100.boxed())
的代码也可以工作。对于集合源代码,您需要编写类似于
joinStreams(stream1,numbers2::stream)