【问题标题】:Intellij IDEA - Evaluate expression with stream API cause errorIntellij IDEA - 使用流 API 评估表达式导致错误
【发布时间】:2018-01-12 19:42:09
【问题描述】:

我正在努力处理包含一些 Stream API 方法的评估表达式。 示例:

sample.reads.stream().filter(s -> s.l.length() < 10)

这也不行:

sample.reads.stream().filter(s -> s.l.length() < 10).collect(Collectors.toList())

给予:

但是,sample.reads.stream().count()sample.reads.stream().toArray() 与任何其他表达式一样工作正常(如果我将流 API 调用放入代码中,它也工作正常)

配置: 爪哇: jdk1.8.0_144

想法: IntelliJ IDEA 2017.3.1(社区版) Build #IC-173.3942.27,建于 2017 年 12 月 11 日 JRE:1.8.0_152-release-1024-b8 amd64 JVM:JetBrains s.r.o 的 OpenJDK 64 位服务器 VM 视窗 10 10.0

更新

抱歉,造成混淆。甚至终端命令也不起作用。我展示了这个例子,因为我发现这个例子是在过滤方法上抛出的,而不是在收集上。如果我添加 .collect() 我会看到同样的错误

更新 2 我认为这与课程无关。即使这给了我同样的错误:

IntStream.range(0, 100).filter(i -> i%2 == 0).toArray()

【问题讨论】:

  • 你应该给出样本的类型,以及 sample.reads 的单个元素的类型,通过错误可以清楚地看出你错过了类路径中的一些依赖项
  • @Hamdi Douss 他们是我的所有课程,位于“edu.gsu.molel”包中。我认为这不是问题,因为 'sample.reads.stream().toArray()' 工作正常
  • 请包含您尝试评估 lambda 的对象架构
  • 他们是在同一个项目还是在不同的项目?
  • 这对我来说似乎工作得很好。我注意到,如果我尝试在正在运行的应用程序中调试没有导入了正确的类的东西,它会因为类似的错误而失败,但我通常可以选择在调试窗口中“导入”它。您是否看到任何错误提示您无权访问 Collectors 类?

标签: java debugging intellij-idea


【解决方案1】:

这有点猜测,但问题似乎是与类路径相关的问题。因此,您会收到无法找到特定软件包的消息。

我不认为这是由于终端或非终端流操作造成的。即使是非终端操作也可以在 IDEA 中进行评估而不会出错。看到这个:

我强烈建议检查 IDEA 中的运行/调试配置,并检查该应用程序正在使用哪个类路径。打开以下对话框并检查“使用模块的类路径”字段中的内容:

其中可能潜入了错误的值。

【讨论】:

  • 是的,你是对的。出于某种原因,我在项目结构中有两个模块——我的项目名称和“主要”。我删除了'main'并重新运行调试,它可以工作!谢谢
  • 这发生在我身上,因为我正在调试 Gradle JavaExec 类型的任务,而 IntelliJ 未设置为“将 IDE 构建操作委托给 Gradle”。在设置中选中该框为我解决了类路径问题。
  • 在我的情况下,如果我使用流 api,我会得到“包不存在”,但普通列表迭代器工作正常。
【解决方案2】:

看这里的 JAVA Stream API 文档 -

流操作分为中间和终端 操作,并组合成流管道。一条流 管道由一个源(例如一个集合、一个数组、一个 生成器函数或 I/O 通道);后跟零个或多个 Stream.filter 或 Stream.map 等中间操作;和一个 Stream.forEach 或 Stream.reduce 等终端操作。

中间操作返回一个新流。他们总是很懒惰; 执行诸如 filter() 之类的中间操作实际上并不 执行任何过滤,而是创建一个新流,当 遍历,包含初始流中匹配的元素 给定谓词。管道源的遍历直到 执行管道的终端操作。

终端操作,例如 Stream.forEach 或 IntStream.sum,可以 遍历流以产生结果或副作用。之后 执行终端操作,考虑流管道 已用完,不能再使用;如果你需要遍历相同的 再次数据源,必须返回数据源获取新的 流。

正如它所说,过滤器是一个中间操作,而不是终端。为了执行或完成流管道,您必须具有终端操作。因此,Intellij 给出了编译错误。

如果是sample.reads.stream().count()sample.reads.stream().toArray()count()toArray() - 都是终端操作,因此可以正常工作。

要解决您的问题,请在 Intellij 表达式求值器中执行类似操作 -

sample.reads.stream().filter(s -> s.l.length() < 10).collect(Collectors.toList());

这里,collect() 是终端操作,它会将结果放入Collectors.toList() 提到的列表中。

【讨论】:

  • 请看我对这个问题的更新。终端操作没用,还是一样的错误。
  • @VyacheslavTsivina 所以你是说相同的表达式在代码中有效?而不是在 Intellij 表达式求值器中?
  • 是的。我在问题中添加了同样不起作用的纯 Java 类的示例
  • 这是一个调试器编译错误(特定于 IntelliJ),它与“未终止”流有何关系?
猜你喜欢
  • 2019-01-09
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 2015-12-11
  • 2021-04-15
相关资源
最近更新 更多