I have this code:
List<Runnable> r = new ArrayList<>();
for(int i = 0; i < 10; i++) {
r.add(new Runnable() {
@Override
public void run() {
System.out.println(i);
}
});
}
It obviously does not compile because i
would need to be final to be used in the anonymous class. But I can't make it final because it is not. What would you do? A solution is to duplicate it but I thought there might be a better way:
List<Runnable> r = new ArrayList<>();
for(int i = 0; i < 10; i++) {
final int i_final = i;
r.add(new Runnable() {
@Override
public void run() {
System.out.println(i_final);
}
});
}
EDIT just to make it clear, I used a Runnable here for the sake of the example, the question is really about anonymous classes, which could be anything else.
In computer programming, a loop counter is a control variable that controls the iterations of a loop (a computer programming language construct).
Adding final keyword makes no performance difference here. It's just needed to be sure it is not reassigned in the loop. To avoid this situation which can lead to confusions.
Use the enumerate() function to count in a for loop, e.g. for index, item in enumerate(my_list): . The function takes an iterable and returns an object containing tuples, where the first element is the index, and the second - the item. Copied!
You are printing the total amount of counter every time the loop is executed. So for i=0 that would be counter=1, for i=1 that would be still counter=1, for i=2 the counter increases to 2, for i=3 the counter remains 2 which is printed etc.
I think your solution is the simplest way.
Another option would be to refactor the creation of the inner class into a factory function that does it for you, then your loop itself could be something clean like:
List<Runnable> r = new ArrayList<>();
for(int i = 0; i < 10; i++) {
r.add(generateRunnablePrinter(i));
}
And the factory function could just declare a final parameter:
private Runnable generateRunnablePrinter(final int value) {
return new Runnable() {
public void run() {
System.out.println(value);
}
};
}
I prefer this refactored approach because it keeps the code cleaner, is relatively self descriptive and also hides away all the inner class plumbing.
Random digression: if you consider anonymous inner classes to be equivalent to closures, then generateRunnablePrinter
is effectively a higher order function. Who said you can't do functional programming in Java :-)
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