Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Foreach loop not working as expected on int array? [duplicate]

I've got a pretty simple loop:

int[] positions = {1, 0, 0}

//print content of positions

for (int i : positions)
{
    if (i <= 0) i = -1;
}

//print content of positions

Now, what I would expect to get is:

array: 1, 0, 0
array: 1, -1, -1

but instead I get

array: 1, 0, 0
array: 1, 0, 0

Just... why?

Kind regards, jellyfish

like image 854
jellyfish Avatar asked May 18 '11 12:05

jellyfish


3 Answers

Because "i" is a copy of an array element and not a reference to it :) You modify a local variable, not an array's element

this code is equivalent to

for(int index = 0; index < array.length; index++) {

int i = array[index];
...
}
like image 171
Łukasz Bownik Avatar answered Oct 22 '22 09:10

Łukasz Bownik


It's simple. If you write

int i = positions[0];

Then you copy positions[0] by value, not by reference. You cannot modify the original value in positions[0] from i. The same applies to assigning i within a foreach loop.

The solution is without a foreach loop

for (int i = 0; i < positions.length; i++)
{
    if (positions[i] <= 0) positions[i] = -1;
}
like image 23
Lukas Eder Avatar answered Oct 22 '22 07:10

Lukas Eder


This happens behind the scenes if we use the enhanced for loop with arrays:

int[] array = {1,2,3,4,5};
for($i = 0; $i<array.length; $i++) {
  int i = array[$i];
  // your statements
  if (i <= 0) i = -1;
}

$i is just a placeholder for an unnamed internal loop variable. See what happens: you assign a new value to i but i is loaded with the next array item in the next iteration.

So, practically spoken, we can't use the variable declared in the enhanced for loop to modify the underlying array.

Reference: JLS 3.0, 14.14.2

like image 2
Andreas Dolk Avatar answered Oct 22 '22 09:10

Andreas Dolk