Joe S
Joe S

Reputation: 3

ArrayList.remove not working with Integer, works with constant

Alright, I'm new to Java, I'm just working through a class, and I've hit a bit of a snag on a program for class. I've managed to work my way through every bit of my final program, except for this last thing.

public static void remove(String studentID)
{
Integer foundLocation = 0;

for (int i = 0; i < studentList.size(); i++)        
    {
        if (studentList.get(i).getStudentID().compareTo(studentID) == 0)
            {
                //This means we have found our entry and can delete it
                foundLocation = i;

            }
    }
System.out.println(foundLocation);
if (foundLocation != 0)
    {
        System.out.println(studentList);

        studentList.remove(foundLocation);
        System.out.println(foundLocation.getClass().getName());


        System.out.println("Student ID removed: " + studentID);
        System.out.println(studentList);
    }
else
    {
        System.out.println("Sorry, " + studentID + " not found.");
    }

The code seems like it should work. But, what I get is that the remove doesn't actually do anything. My extra prints are there to verify. The ArrayList just plain doesn't change.

However, if I just replace:

studentList.remove(foundLocation);

with something like:

studentList.remove(3);

It just removes perfectly.

foundLocation is an Integer.

Can someone explain to me what I've got going on here?

I expect it's blindingly obvious to someone familiar with Java, but I'm missing it.

Upvotes: 0

Views: 440

Answers (3)

Clivant Yeo
Clivant Yeo

Reputation: 21

There are two 'remove' methods in the ArrayList class. One accepts an Object type, the other accepts a int type. By using the Integer object, you are finding an element in the list that is equals to the Integer object. However when you remove by an int type, you are moving by the position of the element in the list.

studentList.remove(foundLocation) will result in the ArrayList checking for a Integer object that is equal to the one that is referenced by foundLocation. This is an object equality check. Two different Integer objects with the same value is deemed as being different even though they have the same numeric value.

studentList.remove(3) will result in the ArrayList to remove the fourth element in the list.

Upvotes: 0

starkshang
starkshang

Reputation: 8578

ArrayList have two remove method,one is remove(int index) and the other is remove(Object object), Your foundLocation type is Integer,when use it it will be a reference,so when you call remove(foundLocation) it will call remove(Object),trying to find a element == foundLocation,it can't find this so remove nothing,once you change the type to int,it will remove element at index foundLocation,refer the method doc.

Upvotes: 0

Thilo
Thilo

Reputation: 262834

This is a bit of a nasty overload that snuck into the Collections API design.

There are two remove methods, one that you call with an int, and one that you call with an Object, and they do very different things.

Unfortunately for you Integer is also an Object, even though you want to use it as an int (and do that in a couple of other places, thanks to the magic of autoboxing that unfortunately does not work for remove).

remove(1) will remove by index (the 2nd element).

remove(Integer.valueOf(1)) will remove the object by its value (the first "1" found in the list).

It would have probably been wiser to give these two methods two different names.

In your case, change foundPosition to be an int.

Upvotes: 4

Related Questions