views:

80

answers:

3

I have an ArrayList, which includes a number of items I want to remove. I have the ids of the items to remove stored in another list. Figured the following code should work trivially, but for some reason, the remove() calls are returning a false value:

  ArrayList<Integer> toRemove = new ArrayList<Integer>();
  ArrayList<JCheckBox> al = new ArrayList<JCheckBox>();

  /* Code that adds a bunch of items to al, and a few integers to toRemove */

  System.out.println("Size before removing: " + al.size());
  for (int i = toRemove.size() - 1; i >= 0; i--) {
    System.out.println("Removing id: " + toRemove.get(i) + ": ");
    System.out.println(al.get(toRemove.get(i)));
    System.out.println(al.remove(toRemove.get(i)));
  }
  System.out.println("Size after removing: " + al.size());

I'd get it if the get() call also returned a false value, but it does actually return the object in question. What am I missing here?

The output of the code above:

Size before removing: 3
Removing id: 2: 
javax.swing.JCheckBox[...]
false
Size after removing: 3
A: 

javax.swing.JCheckBox[...]?

Also, try remove elements by Objects value, like here: http://www.easywayserver.com/blog/java-remove-element-in-arraylist/

Hila's Master
+6  A: 

My guess is you are having a problem with the fact that remove() is overloaded with both int and Object, while get() only takes an int. Try remove(toRemove.get(i).intValue()).

remove(Object) from AbstractCollection will search through the list and remove the given object, which won't be there because you are sending it an Integer and the list only has JCheckBoxs. You are trying to call remove(int), but because you are giving it an Integer, the Object overload is called instead. By converting the Integer to an int, you avoid this problem

Also, can you always be sure the Id in toRemove always equals the index? If toRemove is not in greatest to least order, it won't be.

ILMTitan
Thanks - that worked! And yeah, when I build toRemove, I'm sure it's in order, so that when I go over it in reverse order, I don't need to adjust the indexes as elements are removed.
zigdon
+1  A: 

There are two problems with your code. First, the wrong "toRemove" method is getting invoked. When you call "toRemove.get(i)", the return value is autoboxed into a java.lang.Integer, instead of an int. Therefore, java.util.List#remove(Object) is called instead of java.util.List#remove(int). It's trying to remove an Integer object, and returns false. If you cast the Integer to an int, the desired method will get invoked.

Second problem: each time you remove an element of the list, the indexes of all subsequent elements change, as those elements are "shifted" down. There are several ways to get around this. One is to sort your list of indexes in descending order. Another would be to use a set of indexes, create a new array, and copy into the new array only those elements whose index is not in the set.

dhm