【问题标题】:Local variables referenced from a lambda expression must be final从 lambda 表达式引用的局部变量必须是 final
【发布时间】:2016-11-08 18:12:10
【问题描述】:

我正在尝试从 pojo 创建一个 getValue() 函数,在这个意义上使用细节类值的汇总:

@Transient
public BigDecimal getValue() {
   BigDecimal sum = new BigDecimal(0);

   details.stream().forEach((detail) -> {
      sum = sum.add(detail.getValue());
   });

   return sum;
}

但是我不知道为什么sum = sum.add(detail.getValue());这行会引发这个错误:

从 lambda 表达式引用的局部变量必须是 final 或 有效地最终

你能告诉我我做错了什么吗?谢谢。

【问题讨论】:

  • 错误信息很清楚:如果你想从 lambda 访问局部变量 (sum),它必须是 final。所以你不能按照你展示的方式做到这一点,而必须以另一种方式来处理它。
  • 对,我发布了一个答案说,但后来意识到它仍然行不通,因为他试图修改 sum。
  • 但是如果我声明局部变量 sum 像 `final' 那么我会得到下一个错误:“无法为最终变量 sum 赋值”
  • @axiorema 正确。 Lambda不会允许你像这样修改局部变量。

标签: java


【解决方案1】:

不能从 lambda 中修改变量。这不是你被允许做的事情。

可以在这里做的就是把这个方法写成

return details.stream()
    .map(Detail::getValue)
    .reduce(BigDecimal.ZERO, BigDecimal::add);

【讨论】:

  • 哦,很有趣,我会试着理解这一点;)谢谢
  • 这是一个非常有启发性的答案,我学到了很多。我喜欢mapreduce 函数。谢谢。
【解决方案2】:

好的,只是不要在foreach循环中使用lambda表达式

@Transient
public BigDecimal getValue() {
   BigDecimal sum = new BigDecimal(0);

   for (Detail detail : details) {
      sum = sum.add(detail.getValue());
   }

   return sum;
}

【讨论】:

    【解决方案3】:

    这是我在循环中避免最终 p 的方法,它奏效了。

    public void getSolutionInfo(){      
    ArrayList<Node> graph = Main.graph; 
    
        for(int p=1;p<=Pmax;p++) {          
            final int p2=p;
            System.out.printf("number of node with priority p = %d is %d ",p, graph.stream().filter(node->node.getPriority()==p2).count()); 
        }
    

    【讨论】:

      猜你喜欢
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      • 2019-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-07
      相关资源
      最近更新 更多