gpt4 book ai didi

java - 连接流时意外关闭流

转载 作者:行者123 更新时间:2023-11-29 08:20:30 27 4
gpt4 key购买 nike

使用 Java 8(如果重要的话),我有一个我很难理解的行为。

假设我有一个 Entry这样的类:

static class Entry {
String key;
List<String> values;
public Entry(String key, String... values) {
this.key = key;
this.values = Arrays.asList(values);
}
}

和实例列表:

List<Entry> entries = Arrays.asList(
new Entry("a", "a1"),
new Entry("b", "b1"),
new Entry("a", "a2"));
);

现在我想收集所有具有相同键(并保留不同值)的条目,我偶然发现了“IllegalStateException:流已被操作或关闭”。

生成它的最少代码是:

entries.stream().collect(
Collectors.groupingBy(
e -> e.key,
Collectors.mapping(
e -> e.values.stream(),
Collectors.reducing(Stream.<String>empty(), Stream::concat))
)
);

(我会添加一个 collectingAndThen 来满足我的要求,但这不是我的问题的重点)

我看不到代码的哪一部分在流上使用/起作用。此外,如果我将代码更改为以下内容,它会起作用:

entries.stream().collect(
Collectors.groupingBy(
e -> e.key,
Collectors.mapping(
e -> e.values.stream(),
Collectors.reducing(Stream::concat))
)
);

我宁愿使用前一个代码,因为后者给了我一个 Map<K, Optional<V>>而前者给出了 Map<K, V> .

但问题是:使用中性元素在减少中有什么不同,最终导致(至少)其中一个流被消耗?

最佳答案

主要问题可以归结为这个类似的例子:

Stream<String> identity = Stream.empty();
Stream<String> stream1 = Stream.of("1");
Stream<String> stream2 = Stream.of("2");
Stream.concat(identity, stream1); //works
Stream.concat(identity, stream2); //java.lang.IllegalStateException

换句话说,

Collectors.reducing(Stream.<String>empty(), Stream::concat)

Stream.<String>empty() 创建一个 流对象,并将其重新用作多级缩减中的标识值。幸运的是,您已经有了解决方法。


正如文档中所警告的那样,并在评论中指出,不鼓励重复的流连接:

Use caution when constructing streams from repeated concatenation. Accessing an element of a deeply concatenated stream can result in deep call chains, or even StackOverflowException.

我能想到的另一种方法是在分组之前展平流:

//This yields a Map<String, List<String>>
entries.stream()
.flatMap(v -> v.values.stream().map(val -> new SimpleEntry<>(v.key, val)))
.collect(Collectors.groupingBy(
Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue,
Collectors.toList())));

关于java - 连接流时意外关闭流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59301277/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com