[Java] Rimuovere correttamente un intero da un elenco <intero>


Answers

Puoi usare il casting

list.remove((int) n);

e

list.remove((Integer) n);

Non importa se n è un intero o un intero, il metodo chiamerà sempre quello che ti aspetti.

L'utilizzo di (Integer) n o Integer.valueOf(n) è più efficiente del new Integer(n) poiché i primi due possono usare la cache Integer, mentre i successivi creeranno sempre un oggetto.

Question

Ecco una bella trappola che ho appena incontrato. Considera una lista di numeri interi:

List<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(6);
list.add(7);
list.add(1);

Qualche ipotesi su cosa succede quando esegui list.remove(1) ? Che dire list.remove(new Integer(1)) ? Questo può causare alcuni bug sgradevoli.

Qual è il modo corretto per distinguere tra remove(int index) , che rimuove un elemento dal dato index e remove(Object o) , che rimuove un elemento per riferimento, quando si tratta di liste di interi?

Il punto principale da considerare qui è quello di cui parla @Nikita : la corrispondenza esatta dei parametri ha la precedenza sul box automatico.




Bene, ecco il trucco.

Facciamo due esempi qui:

public class ArrayListExample {

public static void main(String[] args) {
    Collection<Integer> collection = new ArrayList<>();
    List<Integer> arrayList = new ArrayList<>();

    collection.add(1);
    collection.add(2);
    collection.add(3);
    collection.add(null);
    collection.add(4);
    collection.add(null);
    System.out.println("Collection" + collection);

    arrayList.add(1);
    arrayList.add(2);
    arrayList.add(3);
    arrayList.add(null);
    arrayList.add(4);
    arrayList.add(null);
    System.out.println("ArrayList" + arrayList);

    collection.remove(3);
    arrayList.remove(3);
    System.out.println("");
    System.out.println("After Removal of '3' :");
    System.out.println("Collection" + collection);
    System.out.println("ArrayList" + arrayList);

    collection.remove(null);
    arrayList.remove(null);
    System.out.println("");
    System.out.println("After Removal of 'null': ");
    System.out.println("Collection" + collection);
    System.out.println("ArrayList" + arrayList);

  }

}

Ora diamo un'occhiata all'output:

Collection[1, 2, 3, null, 4, null]
ArrayList[1, 2, 3, null, 4, null]

After Removal of '3' :
Collection[1, 2, null, 4, null]
ArrayList[1, 2, 3, 4, null]

After Removal of 'null': 
Collection[1, 2, 4, null]
ArrayList[1, 2, 3, 4]

Ora analizziamo l'output:

  1. Quando 3 viene rimosso dalla raccolta chiama il metodo remove() della raccolta che accetta Object o come parametro. Quindi rimuove l'oggetto 3 . Ma nell'oggetto arrayList è sovrascritto dall'indice 3 e quindi il quarto elemento viene rimosso.

  2. Con la stessa logica di rimozione dell'oggetto null viene rimosso in entrambi i casi nel secondo output.

Quindi per rimuovere il numero 3 che è un oggetto, dovremo esplicitamente passare 3 come object .

E ciò può essere fatto mediante il cast o il wrapping usando la classe wrapper Integer .

Per esempio:

Integer removeIndex = Integer.valueOf("3");
collection.remove(removeIndex);



Si noti che anche se la VM non ha fatto la cosa giusta, cosa che fa, si potrebbe comunque garantire un comportamento corretto usando il fatto che remove(java.lang.Object) opera su oggetti arbitrari:

myList.remove(new Object() {
  @Override
  public boolean equals(Object other) {
    int k = ((Integer) other).intValue();
    return k == 1;
  }
}



list.remove(4) è una corrispondenza esatta di list.remove(int index) , quindi verrà chiamato. Se vuoi chiamare list.remove(Object) fai quanto segue: list.remove((Integer)4) .