【问题标题】:Loop variable used in lambdalambda 中使用的循环变量
【发布时间】:2017-10-11 12:25:53
【问题描述】:
Set<Malfunction> malfunctions= ...
for (final String guideword : guidewords) {
    Malfunction malf = malfunctions.stream()
            .filter(m -> m.getGuideword().equals(guideword))
            .collect(Collectors.toList())
            .get(0);

当我避免使用 guideword 变量,而是使用硬编码值,例如“some_reasonable_string”时,一切正常。

如果我使用循环中的guideword,则会出现问题:有一个Set&lt;Hazard&gt;,它应该并且应该填写在malfunctions中,但后来在malf中为空>.

【问题讨论】:

  • 那么Set&lt;Hazard&gt; 是什么,你在用它做什么?你能提供一个minimal reproducible example吗?
  • 除了collect()get() 你可以只使用findFirst().get()(前提是过滤后至少有一个元素)。

标签: java lambda java-8 closures java-stream


【解决方案1】:

您不能从 lambda 访问循环变量,因为它不是最终的。一种解决方案是在循环中获取它的最终副本。

    for (String guideword : guidewords) {
        // Add this.
        final String thisGuideWord = guideword;
        Malfunction malf = malfunctions.stream().filter(m ->
                m.getGuideword().equals(thisGuideWord))
                .collect(Collectors.toList()).get(0);

但是,正如 GhostCat 所指出的,这里可能对您来说还有一个更根本的问题。

【讨论】:

  • 我想知道为什么他的代码不起作用;我忘记了最后那件事。所以,假设你在这方面是正确的......你得到了我的投票;-)
  • 不幸的是,对于最终副本,上述问题仍然存在。
  • 他的循环变量 final,所以这不是问题。拥有一个临时的 final 变量不会改变任何东西。
【解决方案2】:

为什么要混淆两个概念?迭代老派;但是然后使用流?

建议:使用仅流式解决方案;喜欢:

final List<String> guidewords = Arrays.asList("A", "C");
Set<String> malfunctions = new HashSet<>(Arrays.asList("A", "B"));

System.out.println(malfunctions.stream().filter(e -> guidewords.contains(e)).collect(Collectors.toList()).get(0));

(简化了您的输入以提供适用于所有人的示例;当然您必须对其进行调整以使用contains(e.getGuideword()) 来满足您的要求)。

【讨论】:

    猜你喜欢
    • 2021-02-24
    • 2015-12-08
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 2015-07-18
    • 2013-03-26
    • 2012-07-11
    • 1970-01-01
    相关资源
    最近更新 更多