通过引用调用错误地修改了数组元素

时间:2017-07-19 17:49:31

标签: java

我想向ArrayList添加一个整数数组。在某些条件下,这些要素充满了有效信息;否则数组将填充-1。

    List<int []> starArray = new ArrayList<>();
    int [] star = {-1, -1, -1};
    for (int i = 0; i < 10; i++) {
        if (i < 5) {
            star[0] = i;
            star[1] = 2*i;
            star[2] = 3*i;
            starArray.add(star);
        } else {
            star[0] = star[1] = star[2] = -1;
            starArray.add(star);
        }
    }

问题是,只要它转到else并设置star = 0starArray中的所有元素都将设置为-1。这意味着,在循环之后,我在starArray中得到全-1。我想要这个结果

0#0#0
1#2#3
2#4#6
...
-1#-1#-1

似乎将引用添加到starArray。我想解释的是,我想创建一个包含3个元素的临时数组(星形)。所以星将占用96个字节。然后我将这96个字节移动到ArrayList。接下来,我在star的相同位置创建另外3个元素数据,并将另外96个字节推送到ArrayList。因此,通过将两个star推送到ArrayList,我将使用

96 bytes => original star
96 bytes => first element of ArrayList
96 bytes => second element of ArrayList

那么,我该如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

是的,你是对的。不要在for之外创建数组。在里面创建并将其添加到列表中。否则,它会多次修改同一个对象,并多次添加到列表中,并在最后具有相同的值。

for (int i = 0; i < 10; i++) {
  int [] star = {-1, -1, -1};
        if (i < 5) {
            star[0] = i;
            star[1] = 2*i;
            star[2] = 3*i;
        }
       starArray.add(star);
    }

并且在重复相同的代码时也完全删除了其他内容。

不,如果您查看预期的输出

0#0#0
1#2#3
2#4#6
...
-1#-1#-1

所有数组都有不同的值,你仍然期望一个数组应该保持这个?没有恕我直言。

答案 1 :(得分:4)

您将相同数组的多个引用添加到列表中,因此更改其中一个也将不可避免地更改其他引用。您需要在每次迭代时创建一个新数组:

...
for (int i = 0; i < 10; i++) {
    int[] star = {-1, -1, -1};  // create a new array each iteration
...

在您当前的版本中,图片如下所示:

star          [...]
             /  |  \
          +---+---+---+
starArray |   |   |   |
          +---+---+---+

请注意,所有引用实际上都指向内存中的单个数组。现在,我们正在这样做:

star   [...]  [...]  [...]
           \    |    /
          +---+---+---+
starArray |   |   |   |
          +---+---+---+

即。我们正在创建可以独立修改的多个物理阵列。对不起的ASCII艺术很抱歉。

如果您真的关心内存使用情况,那么您可以尝试的一种方法是为{-1, -1, -1}设置一个数组,只要您不会在这些数组中改变这些数组。未来:

int[] starNegOne = {-1, -1, -1};
for (int i = 0; i < 10; i++) {
    if (i < 5) {
        int[] star = {i, 2*i, 3*i};
        starArray.add(star);
    } else {
        starArray.add(starNegOne);
    }
}

只要您添加{-1, -1, -1}数组,就可以节省空间。

答案 2 :(得分:3)

在每个循环迭代中插入一个新的匿名数组

my $loc = $result->{geometry}{location};
my $lat = $loc->{lat};                      # Can't be omitted here.