La suppression d'un nombre Entier à partir d'une Liste<Integer>
Voici un beau piège j'ai juste rencontré.
Tenir compte d'une liste d'entiers:
List<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(6);
list.add(7);
list.add(1);
Toute supposition sur ce qui se passe lorsque vous exécutez list.remove(1)
? Qu'en est list.remove(new Integer(1))
? Cela peut provoquer quelques vilains bugs.
Quelle est la bonne façon de différencier les remove(int index)
, qui supprime un élément de donnée de l'indice et remove(Object o)
, qui supprime un élément de référence, lorsqu'ils traitent avec des listes d'entiers?
Le principal point à considérer ici est celui @Nikita mentionné - exacte correspondance des paramètres prend la priorité sur l'auto-boxing.
Un: le vrai problème ici est que quelqu'un dans le Soleil un peu pensé avoir (immuable) classes wrapper autour de primitives était intelligent et plus tard, quelqu'un a pensé que le fait d'avoir de l'auto-(onu), la boxe a été encore plus intelligent... ET QUE les GENS continuent à l'AIDE de LAME par DÉFAUT de l'Api, LORSQUE toutes CELLES qui EXISTENT. Pour beaucoup de buts il y a mieux la solution que new Arraylist<Integer>. Par exemple Trove prévoit des choses un TIntArrayList. Plus je programme en Java (SCJP depuis 2001), la moins-je utiliser les classes wrapper et le plus-je utiliser des Api bien conçues (Mine, Google, etc. vient à l'esprit).
OriginalL'auteur Yuval Adam | 2010-12-26
Vous devez vous connecter pour publier un commentaire.
Java appelle toujours la méthode qui convient le mieux à votre argument. Auto boxe et implicite de l'upcasting n'est effectuée que si il n'y a pas de méthode qui peut être appelé sans casting /auto boxe.
La Liste de l'interface spécifie deux méthodes de suppression (veuillez noter que le nommage des arguments):
remove(Object o)
remove(int index)
Qui signifie que
list.remove(1)
supprime l'objet à la position 1 etremove(new Integer(1))
supprime la première occurrence de l'élément spécifié à partir de cette liste.Integer.valueOf(1)
est une meilleure pratique denew Integer(1)
. La méthode statique peut faire la mise en cache, de sorte que vous obtiendrez de meilleures performances.Peter Lawrey proposition est mieux et évite les créations objet.
Peter Lawrey de la proposition ne exactement la même chose que decitrig de la proposition, seulement moins de manière transparente.
Mon commentaire était sur
new Integer(1)
, mais je suis d'accord queInteger.valueOf(1)
ou(Integer) 1
sont équivalentes.OriginalL'auteur aka
Vous pouvez utiliser la conversion
et
Il n'a pas d'importance si n est un entier ou Entier, la méthode sera toujours appeler celui que vous attendez.
À l'aide de
(Integer) n
ouInteger.valueOf(n)
est plus efficace quenew Integer(n)
que les deux premiers peuvent utiliser l'Entier de cache, alors que le plus tard sera toujours de créer un objet.Par l'aide de la coulée, de vous assurer que le compilateur voit le type que vous attendez. Dans le premier cas '(int) n' ne peut être de type int dans le deuxième cas(Entier) n' ne peut être de type Integer. 'n' sera convertie/boîte/sans emballage tel que requis ou vous obtiendrez des erreurs de compilation si elle ne peut pas.
OriginalL'auteur Peter Lawrey
Je ne sais pas sur le bon chemin, mais la façon dont vous l'avez suggéré, fonctionne très bien:
supprime l'élément à une position donnée et
supprime l'objet donné à partir de la liste.
C'est parce que VM essaie d'abord de trouver la méthode déclarée avec exactement le même type de paramètre, et seulement alors, essaie l'autoboxing.
OriginalL'auteur Nikita Rybak
list.remove(4)
est une correspondance exacte delist.remove(int index)
, de sorte qu'il sera appelé. Si vous voulez l'appelerlist.remove(Object)
procédez de la manière suivante:list.remove((Integer)4)
.(Integer)
cast comme vous avez écrit ci-dessus semble être l'approche la plus facile pour moi.Lors de l'utilisation de votre dernière approche, il semble renvoyer un booléen. Lorsque vous essayez d'empiler plusieurs supprime je reçois le message d'erreur que je ne peux pas appeler retirer sur une valeur de type boolean.
OriginalL'auteur Petar Minchev
Il n'y a pas besoin de deviner. Le premier cas entraînera
List.remove(int)
appelle, et l'élément à la position1
sera supprimé. Le deuxième cas entraîneraList.remove(Integer)
appelle, et l'élément dont la valeur est égale àInteger(1)
sera supprimé. Dans les deux cas, le compilateur Java sélectionne correspondant le plus proche de surcharge.Oui, il y a risque de confusion (et les bugs) ici, mais il est assez rare de cas d'utilisation.
Lorsque les deux
List.remove
méthodes ont été définies en Java 1.2, les surcharges n'ont pas été ambiguë. Le problème ne se pose avec l'introduction de médicaments génériques et de l'autoboxing en Java 1.5. En hind-vue, il aurait été mieux si l'une des méthodes de suppression avait été donné un nom différent. Mais il est trop tard maintenant.OriginalL'auteur Stephen C
Noter que même si la machine virtuelle n'a pas fait la bonne chose, ce qu'il fait, vous pouvez toujours vous assurer du bon comportement en utilisant le fait que
remove(java.lang.Object)
opère sur des objets arbitraires:equals
méthode, en particulier, de la Javadoc) "Elle est symétrique: pour toute valeur non nulle de référence les valeurs de x et y, x.equals(y) doit retourner true si et seulement si o.est égal à(x) renvoie la valeur vrai.". En tant que tel, il n'est pas garanti pour fonctionner sur toutes les implémentations deList
, parce que toute la mise en œuvre de la Liste est autorisé à swap x et y dansx.equals(y)
à volonté, depuis la Javadoc deObject.equals
dit que cela devrait être valable.OriginalL'auteur user268396
Simplement j'ai fait comme ci comme suggéré par #decitrig accepté de répondre à premier commentaire.
Cela m'a aidé. Merci encore #decitrig pour votre commentaire. Il peut aider pour certains.
OriginalL'auteur Shylendra Madda
Bien ici, c'est le truc.
Prenons deux exemples ici:
Maintenant, nous allons jeter un coup d'oeil à la sortie:
Maintenant, nous allons analyser la sortie:
Quand 3 est supprimé de la collection qu'il appelle la
remove()
méthode de la collection qui prendObject o
comme paramètre. Par conséquent, il supprime l'objet3
.Mais dans l'objet arrayList il est remplacé par l'indice 3 et donc la 4ème élément est supprimé.
Par la même logique de la suppression d'un Objet null est supprimé dans les deux cas, dans la deuxième sortie.
Donc pour supprimer le numéro
3
qui est un objet, nous allons explicitement besoin de passer 3 comme unobject
.Et qui peut être réalisé par moulage ou d'emballage à l'aide de la classe wrapper
Integer
.Par exemple:
OriginalL'auteur Pritam Banerjee