2010-10-18 12 views
5

Ho un ArrayList per memorizzare alcuni dati, ma ogni volta che rimuovo un elemento dall'elenco, la dimensione non diminuisce, anche quando chiamo ArrayList.trimToSize() . Questo mi sta causando nullPointerExceptions.Java ArrayList.remove() non decrementa la dimensione di ArrayList

Come posso rimuovere un singolo elemento da un ArrayList e le dimensioni dell'elenco() si riducono di conseguenza?

MODIFICA: va bene, ecco il codice. Ecco un po 'di background che devi sapere, dal momento che non posso pubblicare tutto il codice. Ho una ArrayList chiamata _dataHeap e una HashMap chiamata _dataMap. ArrayList è un heap binario contenente un oggetto "findable", che ha una chiave. HashMap esegue il bind da una chiave all'indice dell'oggetto in ArrayList. Questo è un elemento in coda che può essere trovato per elemento usando la HashMap o l'indice usando ArrayList. La chiave può essere qualsiasi oggetto, purché sia ​​univoco per ogni elemento della coda.

Ho eseguito il debug di questa riga per riga e l'heap contiene l'oggetto, anche fino all'Hashcode. Il problema è che l'Oggetto non viene mai rimosso da ArrayList. Questo deve significare che _dataMap.get (element.getKey()) non punta a dove dovrebbe. L'ho verificato però, ho usato un oggetto di prova al di fuori della mia implementazione che esegue il mapping da una stringa a un oggetto personalizzato con String come chiave.

Faccio un oggetto, con la stringa "uno" come chiave. Lo inserisco, quindi provo a rimuoverlo. L'ho passato e tutto si verifica, tranne una cosa: l'oggetto non viene mai rimosso dalla coda. Ha lo stesso Hashcode, la stessa chiave, tutto. Viene rimosso dalla mappa bene, ma non da ArrayList.

Ecco il metodo di rimozione:

public T remove(T element) { 
    //We'll need this data to return the proper value 
    T t = _dataHeap.get(_dataMap.get(element.getKey())); 
    /* 
    * this Swap() call is used to swap our target with the end 
    * of the arraylist. This means that whenever we remove it, 
    * we don't have a change in indexes of the other nodes. 
    * After that, we downHeapify() to fix the whole graph back 
    * to it's functional state. 
    */ 
    swap(_dataMap.get(element.getKey()),length()-1); 
    //Remove from the Heap 
    _dataHeap.remove(_dataMap.get(element.getKey())); 
    _dataHeap.trimToSize(); 
    //Remove from the Map 
    _dataMap.remove(element.getKey()); 
    downHeapify(); 
    return t; 

Spero che questo ti dà una migliore idea di quello che sto facendo male.

MODIFICA IL SECONDO: Santo schifo Ho finalmente risolto! Ho tirato il _dataHeap.get (element.index) nella sua variabile. Questo ha risolto TUTTO!

+0

Puoi pubblicare il codice che stai utilizzando? – highlycaffeinated

+4

Non dovresti aver bisogno di chiamare 'trimToSize()', e 'remove()' _should_ aggiorna correttamente la dimensione della lista. Forse potresti pubblicare un [SSCCE] (http://sscce.org/) che illustra il problema? –

risposta

4

Mi sembra che in realtà non stai rimuovendo nulla. Qual è il valore restituito della tua chiamata remove?

Se si utilizza remove(int), il valore restituito deve essere non nullo. Se si utilizza remove(Object), il risultato dovrebbe essere vero. Altrimenti non hai rimosso nulla. Il tentativo di rimuovere un elemento che non esiste non è un errore, restituisce solo null o false.

+0

Potrebbe esserci qualcosa proprio lì. Ho appena controllato, con una stampa di ArrayList.contains (elemento) prima e dopo la rimozione ... ed entrambi sono falsi. In qualche modo non si aggiunge alla lista giusta. – digiholic

+1

Quindi in realtà non stai rimuovendo nulla. O Mike ha ragione e hai dimenticato di sovrascrivere 'equals' su una classe personalizzata, o l'oggetto che stai cercando di rimuovere non è mai stato aggiunto (o era già stato rimosso in precedenza). –

6

Come ha detto Bemace, controlla se la rimozione funziona come vuoi. Scommetterei i soldi che il tuo metodo equals() sull'oggetto che stai componendo non funziona come te lo aspetteresti, perché non l'hai sovrascritto.

Inoltre, dopo aver eseguito l'override di uguali, fare attenzione anche a ignorare hashCode. Ti farà risparmiare una domanda SO quando il tuo oggetto non funziona con HashMaps. :)

Un consiglio: cerca di utilizzare JUnit. Farà esplodere questi piccoli errori fuori dall'acqua, rendendoti ovvio quando qualcosa non funziona come speri. È molto difficile ignorare una macchia rossa luminosa sulla tua bellissima barra verde.

+3

Re: overriding equals e hashcode, deve leggere questo: http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java –

+0

Ok, ho appena cambiato equals e Hashcode, ma c'è ancora un problema . Non riesco a capirlo in tempo, quindi ho intenzione di risolverlo rapidamente, invece di rimuoverlo, lo sostituirò con null e verificherò i null prima dell'esecuzione. – digiholic

+0

Invia un po 'di codice. Probabilmente possiamo risolverlo rapidamente. – Mike