【问题标题】:Wrong initialization of ArrayList in a loop循环中 ArrayList 的错误初始化
【发布时间】:2012-12-01 07:55:23
【问题描述】:

在 Android 中编码时,我需要一个 ArrayList of Points,我称之为 wormPt。我是通过循环初始化的。

ArrayList<Point> wormPt = new ArrayList<Point>();
Point pt = new Point();
.
.
.
private void initializeWorm() {
    // TODO Auto-generated method stub
    pt.x = 220;
    pt.y = 300;
    for (int i = 0; i <= 5; i++) {
        wormPt.add(pt);
        Log.d("wormdebug", wormPt.toString());

        pt.x -= 5;
    }
    Log.d("wormdebug", wormPt.toString());
}

我的最后一个 log.d 应该报告点 (220,300) (215,300) (210,300) (205,300) (200,300) (195,300)

相反,我的所有分数都是 (190, 300)

这是我的日志数据

11-21 23:48:11.549: D/wormdebug(3273): [Point(220, 300)]
11-21 23:48:11.600: D/wormdebug(3273): [Point(215, 300), Point(215, 300)]
11-21 23:48:11.600: D/wormdebug(3273): [Point(210, 300), Point(210, 300), Point(210, 300)]
11-21 23:48:11.600: D/wormdebug(3273): [Point(205, 300), Point(205, 300), Point(205, 300), Point(205, 300)]
11-21 23:48:11.600: D/wormdebug(3273): [Point(200, 300), Point(200, 300), Point(200, 300), Point(200, 300), Point(200, 300)]
11-21 23:48:11.600: D/wormdebug(3273): [Point(195, 300), Point(195, 300), Point(195, 300), Point(195, 300), Point(195, 300), Point(195, 300)]
11-21 23:48:11.630: D/wormdebug(3273): [Point(190, 300), Point(190, 300), Point(190, 300), Point(190, 300), Point(190, 300), Point(190, 300)]
11-21 23:48:14.669: W/KeyCharacterMap(3273): No keyboard for id 0
11-21 23:48:14.679: W/KeyCharacterMap(3273): Using default keymap: /system/usr/keychars/qwerty.kcm.bin

我试过了 Can't add element to ArrayList in for loop 和其他人,但他们似乎没有同样的问题。任何帮助将不胜感激。 提前致谢。

【问题讨论】:

  • 您似乎错误地认为wormPt.add() 正在克隆pt

标签: java for-loop arraylist initialization


【解决方案1】:

问题在于您的ArrayList 包含对同一对象 的多个引用。您在循环中所做的只是添加相同的引用并改变对象。

如果您更改循环以在每次迭代中创建一个 Point,它将起作用:

int x = 220;
for (int i = 0; i <= 5; i++) {
    wormPt.add(new Point(x, 300));
    x -= 5;
}

了解变量对象引用之间的区别非常重要。 pt 是一个变量。它的值是对Point 对象的引用。除非您要求一个新对象,否则 Java 不会为您创建一个。例如:

Point a = new Point(10, 20);
Point b = a; // Copies the *reference*
a.x = 100;
System.out.println(b.x); // 100

请注意,这并不是将 a 和 b 变量 相互关联——它只是赋予它们相同的值(相同的引用)。因此,您可以稍后将a 更改为对不同Point 的引用,这不会更改b

Point a = new Point(10, 20);
Point b = a; // Copies the *reference*
a.x = 100;
a = new Point(0, 0); // This doesn't affect b, or the object its value refers to
System.out.println(b.x); // 100

在这种情况下,这有点像给 10 个不同的人一张纸,上面写着你的家庭住址。如果这些人中一个访问该地址并将前门涂成绿色,然后另一个人访问该地址,他们将看到一个绿色的前门。

【讨论】:

  • 谢谢你,工作就像一个魅力。我习惯于在 C 中进行编码,我们必须明确声明引用,所以在这种情况下我也在考虑同样的事情。无论如何,再次感谢。
【解决方案2】:

每次添加到ArrayList时都必须创建new Point。相反,只有一个Point 坐标在变化。

【讨论】:

    【解决方案3】:

    这很简单。您正在将相同的对象添加到列表中...

    您应该在循环的每次迭代中创建一个新对象,然后将其添加到列表中。

    尝试类似:

    wormPt.add(new Point(x, 300));
    

    【讨论】:

      【解决方案4】:

      声明

      wormPt.add(pt);

      导致将相同的对象添加到 ArrayList 中。

      您需要将Point 的不同对象添加到arraylist。

      为此,您可以使用
      new Point(x, y)

      你可以创建一个像
      Point p = new Point(x,y)

      这样的对象

      然后将其添加到数组列表中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-15
        • 2019-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-28
        • 1970-01-01
        相关资源
        最近更新 更多