在lambda表达式中使用非final循环变量

时间:2015-09-11 23:42:21

标签: java lambda final executorservice

我试图通过执行器和runnable并行执行100个任务,任务需要使用循环变量:

for (int i = 0; i < 100; i++) {
   executor.execute(() -> {
     doSomething(String.format("Need task number %d done", i));
   }
  });
}

我在'我'说 - Variable used in lambda expression should be effectively final.

之下得到一个波浪形的人

据我所知,循环变量无法成为最终的或有效的最终变量,因为每次迭代都会对其进行更改。我找到了一个简单的解决方法,

for (int i = 0; i < 100; i++) {
   int index = i;
   executor.execute(() -> {
     doSomething(String.format("Need task number %d done", index));
   }
 });
}

这对我来说似乎不是最有效的解决方案,在每次迭代时声明一个新变量。有没有更好的方法呢?

3 个答案:

答案 0 :(得分:12)

  

有更好的方法吗?

我对此表示怀疑。你的解决方案对我来说很好,但如果你想要,你可以将其重写为可能更清晰的代码,如:

IntStream.range(0, 100).forEach(
    i -> executor.execute(
        () -> doSomething(String.format("Need task number %d done", i))
    )
);

答案 1 :(得分:2)

这是使其成功的最直接方式。你不会做得更好。

答案 2 :(得分:0)

将 lambda 表达式代码包装到方法中并将该方法调用到循环中,这样是标准的 lambda 表达式可维护代码

for(int i=1;i<=6;i++){  doSomeThing(i); }


static void doSomeThing(int i)
    { Thread loop=new Thread(()->{print(i);}); // jvm point of view is final
        loop.setPriority(Thread.MIN_PRIORITY);
        loop.start();
    }