webentwicklung-frage-antwort-db.com.de

Wie vergleiche ich zwei ganze Zahlen?

Ich muss zwei Integer Objekte vergleichen (nicht int). Was ist die kanonische Art, sie zu vergleichen?

Integer x = ...
Integer y = ...

Daran kann ich denken:

if (x == y) 

Der Operator == Vergleicht nur Referenzen, daher funktioniert dies nur für niedrigere ganzzahlige Werte. Aber vielleicht setzt das Auto-Boxen ein ...?

if (x.equals(y)) 

Das sieht nach einer teuren Operation aus. Gibt es Hash-Codes, die auf diese Weise berechnet wurden?

if (x.intValue() == y.intValue())

Ein bisschen wortreich ...

EDIT: Vielen Dank für Ihre Antworten. Obwohl ich jetzt weiß, was zu tun ist, sind die Fakten auf alle vorhandenen Antworten verteilt (auch auf die gelöschten :) und ich weiß nicht wirklich, welche ich akzeptieren soll. Ich akzeptiere also die beste Antwort, die sich auf alle drei Vergleichsmöglichkeiten bezieht, oder zumindest die ersten beiden.

34
Daniel Rikowski

Das macht die Methode equals:

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

Wie Sie sehen, gibt es keine Hash-Code-Berechnung, aber einige andere Vorgänge finden dort statt. Obwohl x.intValue() == y.intValue() möglicherweise etwas schneller ist, betreten Sie dort das Gebiet der Mikrooptimierung. Außerdem könnte der Compiler den equals() -Aufruf trotzdem optimieren, obwohl ich das nicht sicher weiß.

Ich würde im Allgemeinen das Primitive int verwenden, aber wenn ich Integer verwenden müsste, würde ich bei equals() bleiben.

33
Jeff

Verwenden Sie die Methode equals. Warum bist du so besorgt, dass es teuer ist?

26
svenningsson
if (x.equals(y))

Das sieht nach einer teuren Operation aus. Gibt es Hash-Codes, die auf diese Weise berechnet wurden?

Es ist keine teure Operation und es werden keine Hash-Codes berechnet. Java berechnet Hash-Codes nicht auf magische Weise, equals(...) ist nur ein Methodenaufruf, der sich von keinem anderen Methodenaufruf unterscheidet.

Die JVM wird höchstwahrscheinlich sogar den Methodenaufruf optimieren (inline den Vergleich, der innerhalb der Methode stattfindet), sodass dieser Aufruf nicht viel teurer ist als die Verwendung von == Für zwei primitive int Werte.

Hinweis: Wenden Sie keine Mikrooptimierungen vorzeitig an. Ihre Annahmen wie "das muss langsam sein" sind höchstwahrscheinlich falsch oder spielen keine Rolle, da der Code keinen Leistungsengpass darstellt.

13
Jesper

Kleiner Hinweis: Seit Java 1.7 hat die Integer-Klasse eine statische compare(Integer, Integer) -Methode, sodass Sie einfach Integer.compare(x, y) aufrufen und damit fertig sein können (Fragen zu Optimierung beiseite).

Natürlich ist dieser Code nicht mit Versionen von Java vor 1.7) kompatibel, daher würde ich empfehlen, stattdessen x.compareTo(y) zu verwenden, das mit Version 1.2 kompatibel ist.

9
ktbiz

Ich würde mit x.equals (y) gehen, weil dies eine konsistente Methode ist, um die Gleichheit für alle Klassen zu überprüfen.

Was die Leistung angeht, ist equals tatsächlich teurer, da es letztendlich intValue () aufruft.

BEARBEITEN: Sie sollten Autoboxen in den meisten Fällen vermeiden. Es kann sehr verwirrend werden, besonders wenn der Autor nicht weiß, was er getan hat. Sie können diesen Code ausprobieren und werden vom Ergebnis überrascht sein.

Integer a = 128;
Integer b = 128;

System.out.println(a==b);
8
ZZ Coder

"gleich" ist es. Um auf der sicheren Seite zu sein, sollten Sie auf Null prüfen:

x == y || (x != null && x.equals(y))

das x == y prüft auf null == null, welches IMHO zutreffen sollte.

Der Code wird von der JIT eingefügt, wenn er häufig genug aufgerufen wird, sodass Leistungsaspekte keine Rolle spielen sollten.

Natürlich ist die Vermeidung von "Integer" zugunsten von "int" der beste Weg, wenn Sie können.

[Hinzugefügt]

Die Null-Prüfung ist auch erforderlich, um sicherzustellen, dass der Gleichheitstest symmetrisch ist - x.equals (y) sollte mit y.equals (x) identisch sein, ist es aber nicht, wenn einer von ihnen Null ist.

2
mfx

Vergleichen Sie die Ganzzahl und geben Sie den Wert in aufsteigender oder absteigender Reihenfolge aus. Sie müssen lediglich die Comparator-Schnittstelle implementieren, die Vergleichsmethode überschreiben und den Wert wie folgt vergleichen:

@Override
public int compare(Integer o1, Integer o2) {
    if (ascending) {
        return o1.intValue() - o2.intValue();
    } else {
        return o2.intValue() - o1.intValue();
    }

}
2
user3468976

Ich bin gerade in meinem Code darauf gestoßen, und es hat eine Weile gedauert, bis ich es herausgefunden habe. Ich habe eine Schnittmenge von zwei sortierten Listen erstellt und in meiner Ausgabe nur kleine Zahlen erhalten. Ich könnte es zum Laufen bringen, indem ich (x - y == 0) anstatt (x == y) während des Vergleichs.

1
Abhinav

Die Integer-Klasse implementiert Comparable<Integer>, So dass Sie versuchen können,

x.compareTo(y) == 0

wenn Sie statt Gleichheit auch nach einem Vergleich dieser ganzen Zahlen suchen,

x.compareTo(y) < 0 zeigt an, ob x kleiner als y ist.

x.compareTo(y) > 0 zeigt an, ob x größer als y ist.

Natürlich ist es in diesen Beispielen ratsam, sicherzustellen, dass x nicht null ist, bevor Sie diese Aufrufe ausführen.

1
jhumble