Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArrayList of integer arrays in Java

Tags:

java

arraylist

everyone.

I'm just getting into Java, and I'm trying to write a simple game where an enemy chases the player on a grid. I'm using the simple algorithm for pathfinding from the Wikipedia page on pathfinding. This involves creating two lists with each list item containing 3 integers. Here's test code I'm trying out to build and display such a list.

When I run the following code, it prints out the same numbers for each array in the ArrayList. Why does it do this?

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(); 
        } 
    }
}
like image 705
vitriolik Avatar asked Dec 02 '12 00:12

vitriolik


1 Answers

First of all, several of the other answers are misleading and/or incorrect. Note that an array is an object. So you can use them as elements in a list, no matter whether the arrays themselves contain primitive types or object references.

Next, declaring a variable as List<int[]> list is preferred over declaring it as ArrayList<int[]>. This allows you to easily change the List to a LinkedList or some other implementation without breaking the rest of your code because it is guaranteed to use only methods available in the List interface. For more information, you should research "programming to the interface."

Now to answer your real question, which was only added as a comment. Let's look at a few lines of your code:

Integer[] point = new Integer[3];

This line creates an array of Integers, obviously.

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

Here you assign values to the elements of the array and then add a reference to the array to your List. Each time the loop iterates, you assign new values to the same array and add another reference to the same array to the List. This means that the List has 10 references to the same array which has been repeatedly written over.

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(); } }

Now this loop prints out the same array 10 times. The values in the array are the last ones set at the end of the previous loop.

To fix the problem, you simply need to be sure to create 10 different arrays.

One last issue: If you declare it as Iterator<Integer[]> it (or Iterator<int[]> it), you do not need to cast the return value of it.next(). In fact this is preferred because it is type-safe.

Finally, I want to ask what the ints in each array represent? You might want to revisit your program design and create a class that holds these three ints, either as an array or as three member variables.

like image 79
Code-Apprentice Avatar answered Sep 24 '22 14:09

Code-Apprentice