Im Vergleich Character, Integer und ähnliche Typen in Java: Verwenden Sie gleich oder ==?

StackOverflow https://stackoverflow.com/questions/735832

  •  09-09-2019
  •  | 
  •  

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.

War es hilfreich?

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:

  1. alle in den Vergleich einbezogenen Werte sind primitive Typen (und vorzugsweise nicht Gleitkommazahlen)
  2. Sie wirklich wissen wollen, ob zwei Referenzen auf dasselbe Objekt verweisen (dies umfasst den Vergleich der enums, 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.

Java Sprache Spec 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.

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top