Richtig entfernen eine Ganzzahl aus einer Liste<Integer>
Hier ist eine schöne Falle, die ich gerade erlebt.
Betrachten Sie eine Liste von Integer-zahlen:
List<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(6);
list.add(7);
list.add(1);
Jede Vermutung darüber, was passiert, wenn Sie ausführen list.remove(1)
? Was list.remove(new Integer(1))
? Dies kann dazu führen, einige böse bugs.
Was ist der richtige Weg, um zu differenzieren zwischen remove(int index)
, die entfernt ein element aus dem gegebenen index und remove(Object o)
, das entfernen eines Elementes durch Verweis, wenn Sie sich mit Listen von ganzen zahlen?
Der wichtigste Punkt zu beachten ist hier das man @Nikita erwähnt - exakt passenden parameter hat Vorrang vor auto-boxing.
A: das eigentliche Problem hier ist, dass jemand bei der Sonne irgendwie dachte, mit (unveränderlichen) - wrapper-Klassen um primitive schlau war und später auf jemand dachte, dass der auto-(un -) Boxen war noch schlauer... UND DASS die LEUTE MIT LAHMEN STANDARD-APIs, WENN BESSERE VORHANDEN. Für viele Zwecke gibt es Art besser die Lösung über new Arraylist<Integer>. Beispielsweise Fundgrube bietet Dinge, die ein TIntArrayList. Je mehr ich das Programm in Java (SCJP seit 2001), die ich weniger Verwendung von wrapper-Klassen und je mehr ich gut-entworfenen APIs (Fundgrube, Google, etc. in den Sinn kommt).
InformationsquelleAutor Yuval Adam | 2010-12-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Java ruft immer die Methode, die am besten zu Ihrem argument. Auto-Boxen und implizite upcasting wird nur durchgeführt, wenn es keine Methode, die aufgerufen werden können ohne casting /auto-Boxen.
Dem List-interface spezifiziert zwei remove-Methoden (bitte beachten Sie die Benennung der Argumente):
remove(Object o)
remove(int index)
Das bedeutet, dass
list.remove(1)
entfernt das Objekt an position 1 undremove(new Integer(1))
entfernt das erste vorkommen des angegebenen Elements aus dieser Liste.Integer.valueOf(1)
ist eine bessere Praxis alsnew Integer(1)
. Die statische Methode tun kann, caching und Z, so erhalten Sie eine bessere Leistung.Peter Lawrey ' s Vorschlag ist besser und vermeidet unnötige Objekt-Kreationen.
Peter Lawrey Vorschlag tut genau das gleiche wie decitrig Vorschlag, nur weniger transparent.
Mein Kommentar war über
new Integer(1)
, aber ich Stimme zu, dassInteger.valueOf(1)
oder(Integer) 1
gleichwertig sind.InformationsquelleAutor aka
Können Sie casting
und
Ist es egal, wenn n ein int-oder Integer die Methode immer aufrufen, die Sie erwarten.
Mit
(Integer) n
oderInteger.valueOf(n)
ist effizienter alsnew Integer(n)
wie die ersten beiden, können die Integer-cache, während die späteren immer ein Objekt erstellen.Mithilfe der Umwandlung, stellen Sie sicher Sie der compiler auf den Typ, den Sie erwarten. Im ersten Fall '(int)' n kann nur werden, geben Sie int im zweiten Fall '(Integer) - n' kann nur vom Typ Ganzzahl. 'n' umgewandelt werden/boxed/ohne Verpackung wie erforderlich, oder Sie bekommen einen compiler-Fehler, wenn Sie es nicht kann.
InformationsquelleAutor Peter Lawrey
Ich don T wissen über 'richtige' Art und Weise, aber die Weise, die Sie vorgeschlagen, funktioniert Prima:
entfernt das element an der angegebenen position und
entfernt das angegebene Objekt aus der Liste.
Es ist, weil die VM beim ersten versuche zu finden, deklarierte Methode mit genau den gleichen parameter-Typ, und erst dann versucht autoboxing.
InformationsquelleAutor Nikita Rybak
list.remove(4)
eine genaue übereinstimmung derlist.remove(int index)
, so wird es genannt. Wenn Sie möchten, rufen Sielist.remove(Object)
Folgendes tun:list.remove((Integer)4)
.(Integer)
Besetzung, wie Sie oben geschrieben haben, scheint das der einfachste Ansatz für mich.Wenn Sie Ihre Letzte Ansatz scheint es ein boolean zurückgibt. Wenn Sie versuchen, um mehrere Stapel entfernt bekomme ich die Fehlermeldung, dass ich nicht aufrufen kann, entfernen Sie auf einen booleschen Wert.
InformationsquelleAutor Petar Minchev
Es gibt keine Notwendigkeit zu erraten. Der erste Fall führt
List.remove(int)
genannt wird, und das element an der position1
entfernt werden. Der zweite Fall führt inList.remove(Integer)
genannt wird, und das element, dessen Wert gleichInteger(1)
entfernt werden. In beiden Fällen wird der Java-compiler wählt den nächsten übereinstimmenden überlastung.Ja, es ist Potenzial für die Verwirrung (und bugs), aber es ist eine ziemlich ungewöhnlich, use-case.
Wenn die beiden
List.remove
Methoden wurden definiert, die in Java 1.2, die überlastet waren nicht mehrdeutig. Das problem entstand mit der Einführung von generics und autoboxing in Java 1.5. In hind-Sicht, wäre es besser gewesen, wenn man die remove-Methoden, hatte ein anderen Namen. Aber ist es jetzt zu spät.InformationsquelleAutor Stephen C
Beachten Sie, dass, auch wenn die VM nicht das richtige tun, was es tut, könnte man immer noch eine ordnungsgemäße Verhalten mit der Tatsache, dass
remove(java.lang.Object)
arbeitet auf beliebige Objekte:equals
- Methode, insbesondere (aus der Javadoc) "Es ist symmetrisch: für jede nicht-null Referenz-Werte x und y, x.equals(y) sollte true zurückgeben, wenn und nur wenn y -.equals(x) true zurück.". Als solches ist es nicht garantiert, um auf allen Implementierungen vonList
, weil die Implementierung der Liste ist nicht erlaubt ein vertauschen der x-und der y inx.equals(y)
, da die Javadoc vonObject.equals
sagt, dass diese gültig sein soll.InformationsquelleAutor user268396
Einfach wollte ich gerne folgenden Vorschlag #decitrig in angenommen Antwort zum ersten Kommentar.
Dieser hat mir geholfen. Nochmals vielen Dank #decitrig für Ihren Kommentar. Es kann helfen, für einige.
InformationsquelleAutor Shylendra Madda
Nun, hier ist der trick.
Nehmen wir zwei Beispiele hier:
Lassen Sie uns jetzt einen Blick auf die Ausgabe:
Lassen Sie uns nun analysieren die Ausgabe:
Als 3 ist aus der Auflistung entfernt, ruft es die
remove()
Methode der Sammlung, die nimmtObject o
als parameter. Daher entfernt er das Objekt3
.Aber in der arrayList-Objekt, das es außer Kraft gesetzt wird, die durch den index 3 und damit die 4. element entfernt wird.
Durch die gleiche Logik der Objekt Entfernung null entfernt ist, in beiden Fällen in der zweiten Ausgabe.
Also um die Zahl zu entfernen
3
was ist ein Objekt, das wir explizit übergeben müssen 3 alsobject
.Werden kann, erfolgt durch Gießen oder wickeln verwenden Sie die wrapper-Klasse
Integer
.ZB:
InformationsquelleAutor Pritam Banerjee