9

みんな。

私はJavaを始めたばかりで、敵がグリッド上でプレイヤーを追いかける簡単なゲームを書こうとしています。パスファインディングに関するウィキペディアのページから、パスファインディングに単純なアルゴリズムを使用しています。これには、各リスト項目に3つの整数が含まれる2つのリストを作成することが含まれます。これが私がそのようなリストを作成して表示しようとしているテストコードです。

次のコードを実行すると、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これにより、インターフェイスで使用可能なメソッドのみを使用することが保証されているため、コードの残りの部分を壊すことなく、LinkedListまたは他の実装に簡単に変更でき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ます。これは、が繰り返し上書きされた同じ配列へのList10個の参照があることを意味します。

イテレータ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個の異なるアレイを作成する必要があります。

最後の問題:(または)itとして宣言する場合、の戻り値をキャストする必要はありません。実際、これはタイプセーフであるため、推奨されます。Iterator<Integer[]> itIterator<int[]> itit.next()

int最後に、各配列のsが何を表しているのかを尋ねたいと思います。プログラムの設計を再検討しint、配列または3つのメンバー変数としてこれらの3つを保持するクラスを作成することをお勧めします。

于 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

他の答えの問題に加えて、it.next()を2回計算します。これにより、イテレータが2回前進しますが、これは明らかにあなたが望むものではありません。このようなコード:

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

しかし、実際には、あなたがエルを使用したのを見ていません。それは合法ですが、意味がないようです。

于 2012-12-02T00:28:58.690 に答える