简体   繁体   English

Java for-each上的行为不一致

[英]Inconsistent behavior on java's for-each

Consider this code: 考虑以下代码:

class Jm44 {

public static void main(String args[]){

      int []arr = {1,2,3,4};
      for ( int i : arr )
      {
         arr[i] = 0;
       }

      for ( int i : arr )
      {
         System.out.println(i);
      }


     }

}

It prints: 它打印:

0 
0 
3 
0

What's this? 这是什么? For-each is supposed to run over all the elements in the array, why would it run arr[3]=0 but not arr[2]=0 ? For-each应该在数组中的所有元素上运行,为什么要运行arr[3]=0但不运行arr[2]=0呢?

If you look at what happens to arr in the first loop, it becomes obvious. 如果您看一下第一个循环中的arr发生了什么,这将变得显而易见。

    int[] arr = {1, 2, 3, 4};
    for (int i : arr) {
        System.out.println("i = " + i);
        arr[i] = 0;
        System.out.println("arr = " + Arrays.toString(arr));
    }

    for (int i : arr) {
        System.out.println(i);
    }

This prints: 打印:

i = 1
arr = [1, 0, 3, 4]
i = 0
arr = [0, 0, 3, 4]
i = 3
arr = [0, 0, 3, 0]
i = 0
arr = [0, 0, 3, 0]
0
0
3
0

You are modifying the values in the array, using the values in the array as indexes. 您正在使用数组中的值作为索引来修改数组中的值。 The "foreach" loop goes through the values of the array, not the indexes of the array. “ foreach”循环遍历数组的 ,而不遍历数组的索引 After removing the syntactic sugar, here is what your foreach loop actually is: 删除语法糖后,这是您的foreach循环实际上是:

    int[] arr = {1, 2, 3, 4};
    for (int index = 0; index < arr.length; index++) {
        int i = arr[index];
        arr[i] = 0;
    }

    for (int i : arr) {
        System.out.println(i);
    }

To be able to index the array, you need to use the traditional for loop, like this: 为了能够对数组建立索引,您需要使用传统的for循环,如下所示:

    int[] arr = {1, 2, 3, 4};
    for (int i = 0; i < arr.length; i++) {
        arr[i] = 0;
    }

    for (int i : arr) {
        System.out.println(i);
    }
int []arr = {1,2,3,4};
      for ( int i : arr )
      {
         arr[i] = 0;
       }

Watch arr in the debugger. 在调试器中观看arr。

1,2,3,4 (initially)
1,0,3,4 (after we change arr[arr[0]], or arr[1])
0,0,3,4 (after we change arr[arr[1]], or arr[0])
0,0,3,0 (after we change arr[arr[2]], or arr[3])
0,0,3,0 (after we change arr[arr[3]], or arr[0] (no change, actually) 

In Java, looping over an array using the 在Java中,使用

for (int i : arr)

syntax loops over the values in the array, not the indexes . 语法遍历数组中的 ,而不是索引 This is different to the JavaScript loop 这与JavaScript循环不同

for (var i in arr)

that loops over indexes. 遍历索引。 Arrays are also indexed starting from 0 - the first item in the array is arr[0] . 数组也从0开始索引-数组的第一项是arr[0] @Esko's answer shows what's actually happening. @Esko的答案显示了实际情况。

because 因为

for ( int i : arr )
      {
         arr[i] = 0;
       }

doesnt set the array to 0s. 不会将数组设置为0s。

surely you meant to say 当然,你的意思是说

for(int i = 0; i < arr.length(); i++){
   arr[i] = 0;
}

You cannot use a foreach loop to set values in an array. 您不能使用foreach循环在数组中设置值。 The for each loop works a little differently than you expect. for每个循环的工作方式与您预期的略有不同。

(Explanation comming) (说明即将到来)

you have to be careful not to confuse index and value of an arrayelement 您必须注意不要混淆数组元素的索引和值

these are the values of the array before and after each iteration of the first loop, including the value of i: 这些是第一个循环的每次迭代前后的数组值,包括i的值:

{1,2,3,4} {1,2,3,4}

{1,0,3,4} i=1 {1,0,3,4} i = 1

{0,0,3,4} i=0 {0,0,3,4} i = 0

{0,0,3,0} i=3 {0,0,3,0} i = 3

{0,0,3,0} i=0 {0,0,3,0} i = 0

不要混淆循环计数器和数组值...我认为这是在这里发生的

Unroll the first loop: 展开第一个循环:

int[] arr = { 1, 2, 3, 4 };
int i;
i = arr[0]; // i = 1
arr[i] = 0; // arr[1] = 0
i = arr[1]; // i = 0
arr[i] = 0; // arr[0] = 0
i = arr[2]; // i = 3
arr[i] = 0; // arr[3] = 0
i = arr[3]; // i = 0
arr[i] = 0; // arr[0] = 0

So, arr[2] (the third element) is never set to zero; 因此, arr[2] (第三个元素)永远不会设置为零; it retains its original value of 3. 它保留其原始值3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM