java for-each上的行为不一致

时间:2009-07-23 19:43:01

标签: java foreach

考虑以下代码:

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);
      }


     }

}

打印:

0 
0 
3 
0

这是什么? For-each应该遍历数组中的所有元素,为什么它会运行arr[3]=0而不是arr[2]=0

8 个答案:

答案 0 :(得分:26)

如果你看一下第一个循环中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);
    }

打印:

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

您正在使用数组中的值作为索引来修改数组中的值。 “foreach”循环遍历数组的,而不是数组的索引。删除语法糖后,这是你的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);
    }

为了能够索引数组,你需要使用传统的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);
    }

答案 1 :(得分:8)

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

在调试器中观察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) 

答案 2 :(得分:3)

在Java中,使用

循环遍历数组
for (int i : arr)

语法循环遍历数组中的 values ,而不是索引。这与 JavaScript 循环

不同
for (var i in arr)

循环索引。数组也从0开始索引 - 数组中的第一项是arr[0]。 @ Esko的回答显示了实际发生的事情。

答案 3 :(得分:2)

因为

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

不会将数组设置为0。

肯定你想说

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

答案 4 :(得分:2)

您不能使用foreach循环来设置数组中的值。每个循环的工作方式与您预期的有所不同。

(解释来了)

答案 5 :(得分:2)

你必须小心,不要混淆arrayelement的索引和值

这些是第一个循环每次迭代之前和之后的数组值,包括i的值:

{1,2,3,4}

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

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

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

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

答案 6 :(得分:2)

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

答案 7 :(得分:1)

展开第一个循环:

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

因此,arr[2](第三个元素)永远不会设置为零;它保留了原来的值3。