Getting a loop iterator for a function inside a loop?

Kind of a dumb problem that I encountered ... Basically, I'm in a For-loop and inside this loop I always call a function to make a button. But in this function, I want to pass a loop iterator as it changes to distinguish between buttons. But then he tells me that I need to make an iterator of the "final" loop, which means it doesn't change!

Ok, my problem will make more sense with some skeleton code:

for(int i = 0; i < appList.size(); i++) { //some other stuff including creating the below button 'btn' btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //set some attribute based on i //but when I do this it only sets based on the greatest value of i (!) } }); } 

Fur is kind of a dumb question. I know ... I'm new to Java, though!

Greetings.

+4
source share
2 answers
 for(int i = 0; i < appList.size(); i++) { final int _i = i; btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // use _i instead of i } }); } 
+4
source

Consider this piece of silly example code:

 int i = 0; obj.invokeThunkAfter10Seconds(new ThunkObject() { public void thunk() { System.out.println(i); } } i = 1; 

ThunkObject contains a reference to i , but i can change, which makes the output unpredictable and depends on when i changed and when thunk is called.

Since Java does not have proper closures (by design, see You cannot reference a non-finite variable inside an inner class defined in another way ), you are clearly not allowed to write non-finite (i.e. mutable) variables like this.

Instead, you should declare a final variable, meaning its initialization, and then not mutable. This means that you can never change i after it has been captured by the inner class.

 final int i = 0; obj.invokeThunkAfter10Seconds(new ThunkObject() { public void thunk() { System.out.println(i); } } // Can't change i here. It will forever now be 0. 

In your example, you cannot just set i as final because you want to change the value at each iteration of the loop. Instead, you can create a copy of the value in the final variable:

 for(int i = 0; i < appList.size(); i++) { //some other stuff including creating the below button 'btn' final int capturedI = i; btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //set some attribute based on capturedI } }); } 
+1
source

All Articles