2010-08-26 12 views
12

Tengo una ArrayList, que incluye una serie de elementos que deseo eliminar. Tengo los identificadores de los elementos para eliminar almacenados en otra lista. Figuraba el siguiente código debería funcionar trivial, pero por alguna razón, el remove() las llamadas se devuelve un valor falso:¿Por qué mi llamada ArrayList.remove (id) no funciona?

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

que lo conseguiría si el get() llamada también devuelve un valor falso, pero realmente devuelve el objeto en cuestión. ¿Que me estoy perdiendo aqui?

La salida del código anterior:

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

¿Puedes publicar declaraciones exactas de 'al' y 'toRemove'? –

+0

Publicadas las definiciones solicitadas. – zigdon

Respuesta

31

Mi conjetura es que está teniendo un problema con el hecho de que remove() está sobrecargado con tanto int y Object, mientras get() sólo toma un int. Pruebe remove(toRemove.get(i).intValue()).

remove(Object) de AbstractCollection buscará a través de la lista y eliminar el objeto dado, que no estará allí, porque lo está enviando un Integer y la lista sólo tiene JCheckBox s. Está intentando llamar al remove(int), pero debido a que le está dando un Integer, en su lugar se llama a la sobrecarga de Objeto. Al convertir el Integer en un int, se evita este problema

Además, ¿siempre se puede estar seguro de que Id en toRemove siempre es igual al índice? Si toRemove no está en el mejor orden posible, no lo será.

+0

Gracias - ¡funcionó! Y sí, cuando construyo en Remover, estoy seguro de que está en orden, de modo que cuando lo revise en orden inverso, no necesito ajustar los índices a medida que se eliminan los elementos. – zigdon

+0

Esta respuesta no considera objetos 'NULL' – Salman

+0

@Salman La pregunta implica que no hay' null's. Si hubiera un 'nulo', la línea sobre la llamada' remove() 'arrojaría un puntero nulo al desempaquetar el argumento en la llamada' get() 'externa. – ILMTitan

1

Hay dos problemas con su código. Primero, se invoca el método "toRemove" incorrecto. Cuando llamas "toRemove.get (i)", el valor devuelto se autoboxea en un java.lang.Integer, en lugar de un int. Por lo tanto, java.util.List # remove (Object) se llama en lugar de java.util.List # remove (int). Está intentando eliminar un objeto entero y devuelve falso. Si convierte el entero a un int, se invocará el método deseado.

Segundo problema: cada vez que elimina un elemento de la lista, los índices de todos los elementos subsiguientes cambian, a medida que esos elementos se "desplazan" hacia abajo. Hay varias formas de evitar esto. Una es ordenar su lista de índices en orden descendente. Otra sería utilizar un conjunto de índices, crear una nueva matriz y copiar en la nueva matriz solo aquellos elementos cuyo índice no está en el conjunto.

Cuestiones relacionadas