Im Vergleich Character, Integer und ähnliche Typen in Java: Verwenden Sie gleich oder ==?
Frage
Ich wollte über etwas in Java, um sicherzustellen: Wenn ich einen Charakter oder eine ganze Zahl oder eine lange und jene Art von Dingen haben, sollte ich gleich oder ist == ausreichend?
Ich weiß, dass mit Streichern es keine Garantien gibt, dass es nur eine Instanz jeder eindeutigen Zeichenfolge ist, aber ich bin über andere geschachtelte Typen nicht sicher.
Meine Intuition ist equals zu verwenden, aber ich möchte sicherstellen, dass ich verschwende Leistung nicht.
Lösung
EDIT: Die Spezifikation macht einige Garantien für Box-Konvertierungen. Von Abschnitt 5.1.7 :
Wenn der Wert p eingerahmt wird wahr, falsch, ein Byte, ein Zeichen im Bereich \ U0000 \ u007f oder ein int oder Kurz Zahl zwischen -128 und 127, dann lassen R1 und R2 sind die Ergebnisse von zwei beliebigen Boxen Umwandlungen von p. Es ist immer der Fall, dass r 1 == r2.
Die Implementierung können verwenden, um einen größeren Pool, Geist Sie.
Ich würde wirklich das Schreiben von Code vermeiden, die allerdings auf, dass beruht. Nicht, weil es scheitern könnte, sondern weil es nicht offensichtlich ist - nur wenige Menschen die Spezifikation, die gut kennen. (Ich dachte vorher, es war abhängig von der Implementierung.)
Sie sollten equals
verwenden oder die zugrunde liegenden Werte vergleichen, d.
if (foo.equals(bar))
oder
if (foo.intValue() == bar.intValue())
Beachten Sie, dass selbst wenn der Autoboxing feste Werte verwenden, garantiert wurde, andere Anrufer immer separate Instanzen sowieso erstellen können.
Andere Tipps
Wenn Sie etwas über den Wert eines Objekts zu vergleichen, verwenden .equals()
.
Auch (und vor allem), wenn diese Objekte sind die primitiven Wrapper-Typen Byte, Zeichen, Kurz, Integer, Long, Float, Double und Boolean.
„==
“ vergleicht immer nur die Objektidentität und du, das ist sehr, sehr selten, was Sie wollen. Und de-facto nie, was Sie wollen mit den primitiven Wrapper.
Nur ==
in einem dieser beiden Szenarien verwenden:
- alle in den Vergleich einbezogenen Werte sind primitive Typen (und vorzugsweise nicht Gleitkommazahlen)
- Sie wirklich wissen wollen, ob zwei Referenzen auf dasselbe Objekt verweisen (dies umfasst den Vergleich der
enum
s, weil dort der Wert auf die Objektidentität gebunden ist)
//Quick test
public class Test {
public static void main(String[] args) {
System.out.println("Are they equal? "+ (new Long(5) == new Long(5)));
}
}
Ausgabe:
"Sind sie gleich? 0"
Antwort:
Nein, sie sind nicht gleich. Sie müssen .equals verwenden oder ihre Grundwerte vergleichen.
Wenn der Wert p eingerahmt wird wahr, falsch, ein Byte, ein Zeichen im Bereich \ U0000 \ u007f oder ein int oder Kurz Zahl zwischen -128 und 127, dann lassen R1 und R2 sind die Ergebnisse von zwei beliebigen Boxen Umwandlungen von p. Es ist immer der Fall, dass r 1 == r2.
und
Diskussion
Idealerweise Boxen eine bestimmte primitive p-Wert würde eine immer Ausbeute identischer Bezug. In der Praxis wird diese kann nicht möglich sein, vorhandene Implementierungstechniken. Die Regeln oben ist ein pragmatischer Kompromiss. Das Nachsatz erfordert darüber bestimmte gemeinsame Werte immer eingerahmt werden in nicht zu unterscheiden Objekte. Das Implementierung kann diese zwischenspeichern, träge oder eifrig.
Für andere Werte, diese Formulierung nicht zulässt, keine Annahmen über die Identität der boxed Werte auf die Programmierer Teil. Dies würde es ermöglichen (Aber nicht erforderlich) Austausch einiger oder alle diese Referenzen.
Damit wird sichergestellt, dass in den meisten üblichen Fällen wird das Verhalten der gewünschte, ohne eine ungebührliche Auferlegung Leistungseinbuße, insbesondere auf kleine Geräte. Weniger Speicher begrenzt Implementierungen könnte, zum Beispiel, cachen alle Zeichen und kurze Hosen, wie auch als ganze Zahlen und sehnt sich in der Bereich von -32K -. + 32K
So, in einigen Fällen == funktionieren wird, in vielen anderen wird es nicht. Immer .equals verwenden, sicher zu sein, da kann man nicht (in der Regel) grantee, wie die Instanzen erhalten.
Wenn die Geschwindigkeit ist ein Faktor (die meisten .equals mit einem == Vergleich starten, oder zumindest sollten sie) und Sie können gurantee, wie sie zugeteilt wurden, und sie passen in den oben genannten Bereichen dann == sicher ist.
Einige VMs können diese Größe erhöhen, aber es ist sicherer, die kleinste Größe anzunehmen, wie sie in der Langauge-Spezifikation angegeben als auf einem bestimmten VM Verhalten zu verlassen, es sei denn, Sie wirklich wirklich wirklich brauchen.
Implementationen der equals (Object o) Methode beginnen fast immer mit
if(this == o) return true;
so mit equals
selbst wenn ==
wahr ist, ist wirklich nicht viel von einer Performance-Einbußen.
Ich empfehle immer * die equals
Methode auf Objekte verwendet wird.
* natürlich gibt es sehr wenige Male, wenn Sie diesen Rat nicht nehmen sollen.
Die allgemeine Antwort ist Nein , Sie sind nicht garantiert, dass für den gleichen numerischen Wert, die lange Objekte, die Sie erhalten die gleichen sind (auch wenn Sie selbst beschränken Long.valueOf zu verwenden ()).
Es ist jedoch möglich, dass Sie eine Leistungsverbesserung, indem man zuerst versuchen, erhalten würden, die Gleichstellung von Referenzen (mit ==) und dann zu prüfen, wenn fehlgeschlagen ist, versucht equals (). Alles hängt von den komparativen Kosten der zusätzlichen == Test und dem Methodenaufruf ... Ihre Leistung kann variieren, aber es lohnt sich eine einfache Loop-Test versuchen, um zu sehen, was besser ist.
Es ist erwähnenswert, dass Auto-Box-Werte Verwendungen Objekt vereinigt, wenn sie verfügbar sind. Aus diesem Grunde (Integer) 0 == (Integer) 0, aber (Integer) 128! = (Integer) 128 für Java 6u13
Ich mag das Ergebnis sehen optisch:
public static void main(String[] args)
{
Integer a = 126; //no boxed up conversion, new object ref
Integer b = 126; //no boxed up conversion, re-use memory address
System.out.println("Are they equal? " + (a == b)); // true
Integer a1 = 140; //boxed up conversion, new object
Integer b1 = 140; //boxed up conversion, new object
System.out.println("Are they equal? " + (a1 == b1)); // false
System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
}
==
vergleicht die Objektreferenz während equals(Object obj)
für Objekt Gleichheit vergleicht. Wenn es jemals mehr als eine Instanz eines Objekts in Existenz gleich sein kann und Sie müssen Verwendung equals
für die Gleichstellung Vergleich.
Beispiele:
Integer i1 = new Integer(12345);
Integer i2 = new Integer(12345);
das sind verschiedene Objektinstanzen sind aber gleich nach Integer der Gleichheit, so müssen Sie equals(Object obj)
verwenden
public enum Gender {
MALE, FEMALE;
}
In diesem Fall gibt es nur eine Instanz von FEMALE
in Existenz sein wird, so ==
sicher zu verwenden ist.