I'm trying to execute 100 tasks all in parallel via executors and runnable, the task needs to use the loop variable:
for (int i = 0; i < 100; i++) {
executor.execute(() -> {
doSomething(String.format("Need task number %d done", i));
}
});
}
I get a squiggly under 'i' saying - Variable used in lambda expression should be effectively final.
A loop variable, as far as I'm aware, cannot be made final or effectively final, since it is being changed with each iteration. I found a simple workaround,
for (int i = 0; i < 100; i++) {
int index = i;
executor.execute(() -> {
doSomething(String.format("Need task number %d done", index));
}
});
}
This doesn't seem the most effective solution to me, declaring a new variable at every iteration. Is there a better way of doing this?
A lambda expression can use a local variable in outer scopes only if they are effectively final.
Forcing the variable to be final avoids giving the impression that incrementing start inside the lambda could actually modify the start method parameter.
A lambda expression can't define any new scope as an anonymous inner class does, so we can't declare a local variable with the same which is already declared in the enclosing scope of a lambda expression. Inside lambda expression, we can't assign any value to some local variable declared outside the lambda expression.
Variable defined by the enclosing scope of a lambda expression are accessible within the lambda expression. For example, a lambda expression can use an instance or static variable defined by its enclosing class.
Is there a better way of doing this?
I doubt it. Your solution looks fine to me, but if you want you can rewrite it into possibly clearer code like:
IntStream.range(0, 100).forEach(
i -> executor.execute(
() -> doSomething(String.format("Need task number %d done", i))
)
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With