Suppression d'un item de liste en java
Un comportement particulier des objets de type List
en java relevé par un collègue au boulot et qui peut parfois induire une source imprévue de bugs (oui : il y a des sources « prévisibles » de bugs). Le problème apparaît si on ne fait pas attention à ce que l'on utilise pour supprimer un élément de la liste en fonction de son index : un entier type primitif ou un entier objet.
Imaginons un objet quelconque :
class MyClass {
private String name;
public MyClass(String name) { this.name = name; }
public String toString() { return name; }
}
On stocke une série de ces objets dans une liste :
List<MyClass> myList = new ArrayList<MyClass>();
myList.add(new MyClass("foo"));
myList.add(new MyClass("bar"));
MyClass
.L'API de récupération d'un membre de la liste se résume à une méthode get
qui prend en paramètre l'index du membre que l'on souhaite réupérer. On peut indiféremment utiliser un entier de type primitif (int
) ou un entier objet (Integer
) :
// Utilisation d'un entier type primitif
myList.get(0)); // => foo
// utilisation d'un entier objet
myList.get(new Integer(0)); // => foo
Passons à l'API de suppression maintenant (méthode remove
) car c'est là que les problèmes peuvent survenir si l'on ne fait pas attention. La méthode est en effet surchargé : une première forme prend en paramètre un entier de type primitif pour supprimer un membre de la liste par son index, une seconde est caractérisée par un paramètre de type Object
et permet la suppression d'un membre en le désignant directement. Donc, quand on utilise un entier objet, c'est cette méthode qui est appelée : l'entier est considéré comme un membre de la liste et non comme l'index du membre à supprimer. La suppression se passera donc mal...
// Utilisation d'un entier type primitif
myList.remove(0)); // => foo (la suppression s'est bien passé).
// utilisation d'un entier objet
myList.remove(new Integer(0)); // => false (pas de suppression)
[java-remove-int]: http://docs.oracle.com/javase/7/docs/api/java/util/List.html#remove%28int%29 [java-remove-obj]: http://docs.oracle.com/javase/7/docs/api/java/util/List.html#remove%28java.lang.Object%29