代码之家  ›  专栏  ›  技术社区  ›  Pawan

在封闭作用域中定义的局部变量计数必须是final或实际上是final[duplicate]

  •  0
  • Pawan  · 技术社区  · 6 年前

    Local variable count defined in an enclosing scope must be final or effectively final
    

    public static void main(String[] args) {
    
      List<String> names = new ArrayList<String>();
      names.add("Ajeet");
      names.add("Negan");
      names.add("Aditya");
      names.add("Steve");
    
      int count = 0;
    
      names.stream().forEach(s->
      {
        if(s.length()>6)
            count++;
      });
    }
    
    3 回复  |  直到 6 年前
        1
  •  7
  •   Elliott Frisch    6 年前

    你不能访问非- final 来自lambda中外部作用域的变量。但你不需要在这里,你可以 filter 这个 stream 根据你的标准和 count

    long count = names.stream().filter(s -> s.length() > 6).count();
    
        2
  •  6
  •   ernest_k Petronella    6 年前

    声明 count++; 正在重新分配变量 count .

    这在lambda表达式中是不允许的。lambda中引用的局部变量必须是final(或者实际上是final,这意味着它没有显式声明为final,但是如果 final (已添加)

    另一种方法是使用原子整数:

    AtomicInteger count = new AtomicInteger();
    
    names.stream().forEach(s -> {
        if (s.length() > 6)
            count.incrementAndGet();
    });
    

    注意 只有在需要修改局部变量时才应该使用原子整数。如果这一切只是为了计算 计数 变量,那么EliotFrish答案中的方法更好。

        3
  •  0
  •   Lino    6 年前

    这个答案只是为了提供一个更广泛的范围来克服这个错误。

    您可以定义自己的消费者,其中包括:

    class CountingConsumer implements Consumer<String>{
        int count;
    
        public void accept(String s){
            if(s.length() > 6){
                count++;
            }
        }
    }
    

    然后将此新类的实例传递给使用者:

    CountingConsumer countingConsumer = new CountingConsumer();
    names.forEach(countingConsumer);
    

    最终可以在迭代后提取计数:

    System.out.println(countingConsumer.count);
    

    int count = 0;
    for(String s : names){
        if(s.length() > 6){
            count++;
        }
    }