java - 为什么在同一流上调用两个终端操作后不会抛出 IllegalStateException?

标签 java java-stream illegalstateexception

我了解到 collect()forEach() 都是流终端操作,在同一个流上调用它们会抛出 非法状态异常。但是,以下代码可以成功编译并按升序打印每个字符串的长度。不会引发任何异常。怎么会这样?

List<String> list = Arrays.asList("ant", "bird", "chimpanzee", "dolphin");
list.stream().collect(Collectors.groupingBy(String::length))
        .forEach((a, b) -> System.out.println(a));

最佳答案

您调用的 forEach 方法不是 Stream::forEach 方法,而是 Map::forEach方法,就像您在 collect(...) 的返回值上调用它一样,它是一个 MapMap::forEach 方法的一个功能是它采用 BiConsumer,而不是 Consumer。流的 forEach 永远不会采用带有两个参数的 lambda!

因此,您只调用一个终端操作,即流上的 collect 。在那之后,您再也没有对流执行任何操作(您开始使用返回的 Map ),这就是为什么没有抛出 IllegalStateExcepton 的原因。

要在同一个流上实际调用两个终端操作,您需要首先将流放入变量中:

List<String> list = Arrays.asList("ant", "bird", "chimpanzee", "dolphin");
Stream<String> stream = list.stream(); // you need this extra variable.
stream.collect(Collectors.groupingBy(String::length));
stream.forEach((a) -> System.out.println(a)); // this will throw an exception, as expected

关于java - 为什么在同一流上调用两个终端操作后不会抛出 IllegalStateException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58250277/

相关文章:

Java Streams - 如果比较器存在则排序

java - 如何知道属性文件中是否存在属性?

java - 将双foreach和if语句重构为java 8解决方案

java - Parse 中的 objectId 始终为 NULL

java - 如何合并相似对象的列表,但用 Java 8 总结一些属性

java - 如何在没有按钮的 onClick 方法的情况下关闭 AlertDialog.Builder?

java - 当我尝试从 Activity 类调用函数时崩溃

java - 为什么我的 Activity 在添加 fragment 后会被破坏(#2)?

java - 如何更改可执行的jar文件图标?

javascript - 获取更新的 HTML 源代码