【问题标题】:Why doesn't this for-each loop work? [duplicate]为什么这个 for-each 循环不起作用? [复制]
【发布时间】:2010-10-17 17:43:48
【问题描述】:

在这段代码中,为什么我的数组没有按照我的意愿进行初始化?是 for-each 循环不是为此而设计的,还是我没有正确使用它?

    int[] array = new int[5];

    //initialise array -> Doesn't work! Array still full of 0's
    for(int i : array)
        i = 24;

【问题讨论】:

  • 其他问题不应该重复吗?这是第一次。

标签: java foreach


【解决方案1】:

for-each 循环不适用于这种情况。您不能使用 for-each 循环来初始化数组。你的代码:

int[] array = new int[5];
for (int i : array) {
    i = 24;
}

将转换为如下内容:

int[] array = new int[5];
for (int j = 0; j < array.length; j++) {
    int i = array[j];
    i = 24;
}

如果这是一个对象数组,它仍然会失败。基本上,for-each 将集合或数组中的每个条目依次分配给您提供的变量,然后您可以使用该变量。该变量等效于数组引用。它只是一个变量。

For-each 不能用于初始化 any 数组或 Collection,因为它循环遍历数组或 Collection 的当前内容,为您提供每个 value 一个时间。 for-each 中的变量不是数组或集合引用的代理。编译器不会用“array[index]”替换您的“i”(来自“int i”)。

如果你有一个日期数组,例如,试试这个,代码:

Date[] array = new Date[5];
for (Date d : array) {
    d = new Date();
}

会被翻译成这样的:

Date[] array = new Date[5];
for (int i = 0; i < array.length; i++) {
    Date d = array[i];
    d = new Date();
}

如您所见,它不会初始化数组。你最终会得到一个包含所有空值的数组。

注意:我把上面的代码编译成.class文件,然后用jad反编译。这个过程给了我以下代码,由 Sun Java 编译器 (1.6) 从上面的代码生成:

int array[] = new int[5];
int ai[];
int k = (ai = array).length;
for(int j = 0; j < k; j++)
{
    int i = ai[j];
    i = 5;
}

【讨论】:

  • 其实它不是用迭代器转换成while循环吗?
  • 我并不是要给出确切的翻译,而是想知道为什么它不起作用。
  • @Matt Olenik:不,显然不是。我编译了代码,然后用jad查看生成了什么代码,至少对于一个数组,生成的是for循环,而不是while循环。
【解决方案2】:

使用

java.util.Arrays.fill(array, 24)

如果您要初始化为相同的值。除此之外,Eddie 在他对 for-each 结构的翻译中非常到位。

【讨论】:

  • 不错!从现在开始我会经常使用这个类!
【解决方案3】:

改为这样做:

int[] array = new int[5];

// initialise array -> Will work now
for(int i = 0 ; i< array.length ; i++)
    array[i] = 24 ;

【讨论】:

  • 我不想每次都写出来。看起来我无法摆脱它.. :(
  • 欢迎来到程序员生活中的重复打字方面
【解决方案4】:

int 是系统中的原始类型,因此您实际上得到的是数组中单元格值的副本,而不是您可以分配给数组中的那个单元格的引用......

让我试着解释一下。如果您有一个 X 数组,其中 X 是一个具有数据成员的类,您将在每次迭代中获得对不同单元格的引用,并且能够通过调用其上的函数来更改其状态(例如,setValue) .

当你有 int 时,情况就不同了,你的 int 不是一个引用,它是堆栈上的一个实际值,因为它是一个原始类型,所以在每次迭代中,for 将一个值从数组复制到 i。然后你更新你的 i,但这对数组没有影响。

【讨论】:

  • 然而,这并不是失败的确切原因。它与 int 是原始的无关。您不能使用 for-each 来初始化 any 数组,无论其内容是否原始。
  • 除非你的类有一个明确的 setValue() 你想调用。
  • 如果使用对象数组,此代码不会初始化数组。它与这里的变量是原始的无关。
  • 因为他正在使用作业。但如果这些是对象,他就不会使用赋值来设置值。
  • 如果这是一个对象数组的循环,你最终会得到一个满是 null 的数组。看我的回答。您不能使用 for-each 循环初始化 any 数组或 Collection。
【解决方案5】:

i 只是数组中该点的 int 的副本,而不是对它的引用。在这种情况下,for-each 循环不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 2019-07-23
    • 2019-01-09
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多