为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

繁星coding 2023-09-27 15:25:32
我知道collect()和forEach()都是流终端操作,并且在同一个流上调用它们会抛出一个IllegalStateException. 但是,以下代码可以成功编译并按升序打印每个字符串的长度。不会引发任何异常。怎么会这样呢?List<String> list = Arrays.asList("ant", "bird", "chimpanzee", "dolphin");list.stream().collect(Collectors.groupingBy(String::length))        .forEach((a, b) -> System.out.println(a));
查看完整描述

2 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

您调用的方法forEach不是Stream::forEach方法,而是Map::forEach方法,因为您在 的返回值(collect(...)Map. 该方法的一个特点Map::forEach是它采用BiConsumer, 而不是Consumer。流forEach永远不会接受带有两个参数的 lambda!

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

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

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



查看完整回答
反对 回复 2023-09-27
?
MMTTMM

TA贡献1869条经验 获得超4个赞

生成的流list.stream()由该操作消耗collect。但作为分组结果的操作是Map<Integer, List<String>>根据字符串的大小生成的。

thenforEach调用Map由 生成的this 条目,因此后者collect不会抛出异常。IllegalStateException


查看完整回答
反对 回复 2023-09-27
  • 2 回答
  • 0 关注
  • 97 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信