Ryan
Ryan

Reputation: 289

Wrong initialization of ArrayList in a loop

While coding in Android, I needed an ArrayList of Points which I called wormPt. I initialized it through a loop.

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

My last log.d should report points (220,300) (215,300) (210,300) (205,300) (200,300) (195,300)

Instead, all my points are (190, 300)

Here is my log data

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

I tried Can't add element to ArrayList in for loop and others, but they don't seem to be having the same problem. Any help will be appreciated. Thanks in advance.

Upvotes: 1

Views: 1211

Answers (4)

Pratik
Pratik

Reputation: 1541

The Statement

wormPt.add(pt);

causing addition of same object into ArrayList.

You need to add different object of Point to arraylist.

for that you can use
new Point(x, y)
or
you can create an object like
Point p = new Point(x,y)

and then add it to the arraylist.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500675

The problem is that your ArrayList contains several references to the same object. All you're doing in the loop is adding the same reference and mutating the object.

If you change the loop to create a new Point on each iteration, it will work:

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

It's very important to understand the difference between variables, objects and references. pt is a variable. Its value is a reference to a Point object. Unless you ask for a new object, Java won't create one for you. For example:

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

Note that this isn't associating the a and b variables with each other - it's just giving them the same value (the same reference). So you could later change a to be a reference to a different Point, and that wouldn't change 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

In this case, it's a bit like giving 10 different people a piece of paper with your home address on. If one of those people visits the address and paints the front door green, then another of them visits the address, they'll see a green front door.

Upvotes: 5

Bharat Sinha
Bharat Sinha

Reputation: 14363

It's pretty simple. You are adding the same object to the list...

you should created a new object in each iteration of the loop and then add it to the list.

Try something like:

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

Upvotes: 0

bellum
bellum

Reputation: 3710

You must create new Point every time when adding to ArrayList. Instead there is only one Point with changing coordinates.

Upvotes: 1

Related Questions