9

每个人。

我刚接触Java,我正在尝试编写一个简单的游戏,其中敌人在网格上追逐玩家。我正在使用来自维基百科寻路页面的简单算法进行寻路。这涉及创建两个列表,每个列表项包含 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(); 
        } 
    }
}
4

4 回答 4

13

首先,其他几个答案具有误导性和/或不正确。请注意,数组是一个对象。因此,无论数组本身是否包含原始类型或对象引用,您都可以将它们用作列表中的元素。

接下来,将变量声明为List<int[]> list优于将其声明为ArrayList<int[]>。这使您可以轻松地更改List为 aLinkedList或其他一些实现,而不会破坏其余代码,因为它保证只使用List接口中可用的方法。有关更多信息,您应该研究“接口编程”。

现在回答您的真正问题,该问题仅作为评论添加。让我们看一下您的几行代码:

Integer[] point = new Integer[3];

Integer显然,这一行创建了一个 s 数组。

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

在这里,您将值分配给数组的元素,然后将对该数组的引用添加到您的List. 每次循环迭代时,您都会为同一数组分配新值,并将对同一数组的另一个引用添加到List. 这意味着List有 10 个对已被重复写入的同一数组的引用。

迭代器它 = 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 个不同的数组。

最后一个问题:如果您声明itIterator<Integer[]> it(或Iterator<int[]> it),则不需要强制转换的返回值it.next()。事实上,这是首选,因为它是类型安全的。

最后想问一下int,每个数组中的s代表什么?您可能想要重新审视您的程序设计并创建一个包含这三个ints 的类,或者作为数组或作为三个成员变量。

于 2012-12-03T00:18:21.297 回答
2

你在这里有一个额外的)

element = (int[])it.next()); //with the extra parenthesis the code will not compile 

应该:

element = (int[])it.next(); 
于 2012-12-02T00:30:23.820 回答
2

我强烈建议将 3 个数字的整数数组包含在一个有意义的类中,该类将保存、显示和控制 3 个整数的数组。

然后,在您的主目录中,您可以拥有该类对象的不断增长的 ArrayList。

于 2012-12-02T00:35:54.487 回答
1

除了另一个答案中的问题之外,你 cal it.next() 两次,这导致迭代器向前移动两次,显然这不是你想要的。像这样的代码:

element = (int[])it.next()); 
String el = (String)element;

但实际上,我没有看到你使用过 el。虽然是合法的,但似乎毫无意义。

于 2012-12-02T00:28:58.690 回答