+ 1

Can someone explain how this works?

int[] a = {1,2,3,4,1}; for (int n:a) a[n]=0; for (int n:a) System.out.print(n) Why does this output 00301 Instead of 00000?

27th Sep 2019, 6:33 AM
Joe Vellinga
Joe Vellinga - avatar
8 Respostas
+ 2
Haha this one is a little tricky if you didn't look closely, the output would be 00000 only if n was 0 to a.length-1 for (int n = 0; n < a.length; ++n) a[n] = 0; Here n is actually a[i] if i was 0 to a.length-1 for (int n : a) a[n] = 0; // is the same as for (int i = 0; i < a.length; ++i) { int n = a[i]; a[n] = 0; // a[a[i]] = 0; }
27th Sep 2019, 6:44 AM
jtrh
jtrh - avatar
+ 2
When you see an enhanced for-loop such as: for ( int n : a ) You read the line as "for each int value <n> in <a>". The value of <n> changes with each loop iteration. As follows: Iteration | <n> value 1 | 1 2 | 2 3 | 3 4 | 4 5 | 1 When you refer to an array element by index `a [n] = 0;` you are not getting desired output because value of <n> here does not correspond to array element's index. Instead, <n> is the element's value. IIRC primitive types in Java are immutable. So you cannot use enhanced for-loop to modify a container's data. Even if you try `n = 0;` in place of `a[n] = 0;` it still wouldn't work. Take the regular for-loop approach using the index to modify data in a container. Like the first example shown in jtrh answer. Hth, cmiiw
27th Sep 2019, 9:06 AM
Ipang
+ 1
Ipang yes you are right they are immutable, but not in that sense https://stackoverflow.com/questions/18037082/are-java-primitives-immutable. Setting n = 0 in that loop will not change that element in the array because they are passed by value and not by reference.
27th Sep 2019, 10:59 AM
jtrh
jtrh - avatar
+ 1
Ipang Oops! Yes that was for you. Lol sorry for mentioning you op
27th Sep 2019, 2:22 PM
jtrh
jtrh - avatar
+ 1
jtrh okay so then it would iterate as: a[1]=0 // {1,0,3,4,1} a[0]=0 // {0,0,3,4,1} a[3]=0 // {0,0,3,0,1} a[0]=0 // {0,0,3,0,1} a[1]=0 // {0,0,3,0,1} I think I get it now thanks a bunch 😁
27th Sep 2019, 2:53 PM
Joe Vellinga
Joe Vellinga - avatar
0
Joe Vellinga I don't understand what you mean by using Integer, because it is also immutable (it doesn't let you set the underlying int). That stackoverflow answer explained what about primitives were immutable. It is that the type int is immutable mainly because it is a scalar type so there's nothing to really mutate under it. int more or less defines one value in a set of possible values which are ints. It doesn't have a value, it *is* the value, making int more of a "type" than an encapsulating "class". If we look at the for each loop using the for range loop, it becomes obvious what n = 0 does which is mutating the value of the variable, the variable itself isn't immutable. for (int i = 0; i < a.length; ++i) { int n = a[i]; // n has a copy of the value in a[i] n = 0; // the n which exists within this loop } In Java actual passing by reference isn't allowed (only passing object references by value using implicit pointers) https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value, but in other languages like C++ has actual pass by reference semantics. for (int& n : a) n = 0; will actually change the value in the array a through the reference.
27th Sep 2019, 1:44 PM
jtrh
jtrh - avatar
0
jtrh You mentioned the wrong person. I believe you directed your most recent response to me instead. Yes you are right, using Integer doesn't help either here because the <n> is scoped to the loop. I'm taking my wrong answer out.
27th Sep 2019, 2:15 PM
Ipang
0
jtrh Yes, so I figured 😁
27th Sep 2019, 2:59 PM
Ipang