我正在尝试编写一个简单的游戏,其中敌人在网格上追逐玩家。我正在使用维基百科寻路页面中的简单算法进行寻路。这涉及创建两个列表,每个列表项包含 3 个整数。这是我正在尝试构建和显示此类列表的测试代码。
当我运行以下代码时,它为 ArrayList 中的每个数组打印出相同的数字。为什么要这样做?
public class ListTest {
public static void main(String[] args) {
ArrayList<Integer[]> list = new ArrayList<Integer[]>();
Integer[] point = new Integer[3];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 3; j++) {
point[j] = (int)(Math.random() * 10);
}
//Doesn't this line add filled Integer[] point to the
//end of ArrayList list?
list.add(point);
//Added this line to confirm that Integer[] point is actually
//being filled with 3 random ints.
System.out.println(point[0] + "," + point[1] + "," + point[2]);
}
System.out.println();
//My current understanding is that this section should step through
//ArrayList list and retrieve each Integer[] point added above. It runs, but only
//the values of the last Integer[] point from above are displayed 10 times.
Iterator it = list.iterator();
while (it.hasNext()) {
point = (Integer[])it.next();
for (int i = 0; i < 3; i++) {
System.out.print(point[i] + ",");
}
System.out.println();
}
}
}
原文由 vitriolik 发布,翻译遵循 CC BY-SA 4.0 许可协议
首先,其他几个答案具有误导性和/或不正确。请注意,数组是一个对象。因此,您可以将它们用作列表中的元素,无论数组本身是否包含原始类型或对象引用。
接下来,将变量声明为
List<int[]> list
优于将其声明为ArrayList<int[]>
。这使您可以轻松地将List
更改为LinkedList
或其他一些实现,而不会破坏其余代码,因为它保证仅使用List
中可用的方法---
界面。有关更多信息,您应该研究“接口编程”。现在回答您真正的问题,该问题仅作为评论添加。让我们看一下您的几行代码:
显然,这一行创建了一个
Integer
的数组。在这里,您为数组的元素赋值,然后将对该数组的 引用 添加到您的
List
。每次循环迭代时,您都将新值分配 给同一个数组,并将 对同一个数组的另一个引用 添加到List
。这意味着List
有 10 个 对同一数组的 引用,这些数组已被重复覆盖。迭代器it = list.iterator(); while (it.hasNext()) { point = (Integer[])it.next(); for (int i = 0; i < 3; i++) { System.out.print(point[i] + “,”); } System.out.println(); } }
现在这个循环打印出 同一个数组 10 次。数组中的值是在上一个循环结束时设置的最后一个值。
要解决此问题,您只需确保创建 10 个 不同的 数组即可。
One last issue: If you declare
it
asIterator<Integer[]> it
(orIterator<int[]> it
), you do not need to cast the return value ofit.next()
.事实上,这是首选,因为它是类型安全的。最后想问下每个数组中的
int
代表什么?您可能想重新审视您的程序设计并创建一个类来保存这三个int
s,作为数组或作为三个成员变量。