Ich habe festgestellt, dass die java.lang.Integer
Implementierung der compareTo
Methode wie folgt aussieht:
public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
Die Frage ist, warum Vergleich statt Subtraktion verwendet wird:
return thisVal - anotherVal;
java
optimization
integer
comparison
integer-overflow
Vladimir
quelle
quelle
Integer.compare(thisVal, anotherVal)
den ternären Ausdruck verwenden, anstatt ihn zu schreiben.Antworten:
Dies ist auf einen ganzzahligen Überlauf zurückzuführen. Wenn
thisVal
es sehr groß undanotherVal
negativ ist, ergibt das Subtrahieren des letzteren vom ersteren ein Ergebnis, das größer ist alsthisVal
das, das in den negativen Bereich überlaufen kann.quelle
thisVal
muss nicht groß sein.thisVal
könnte sogar Null sein undanotherVal
seinInteger.MIN_VALUE
und Sie haben bereits einen Überlauf. Und denken Sie daran, dass es natürlich auch umgekehrt sein könnte,thisValue
sehr klein undanotherVal
ziemlich groß, einen Abstand zu haben, der über denint
Wertebereich hinausgeht.Der Subtraktions- "Trick" zum Vergleichen zweier numerischer Werte ist gebrochen !!!
int a = -2000000000; int b = 2000000000; System.out.println(a - b); // prints "294967296"
Hier ist
a < b
docha - b
noch positiv.Verwenden Sie diese Redewendung NICHT. Es funktioniert nicht.
Außerdem , selbst wenn es funktioniert , wird es nicht eine wesentliche Verbesserung der Leistung, und kann in der Tat Kosten Lesbarkeit.
Siehe auch
quelle
((long)a - b)
ich es nicht weiß, sollte es einfach funktionieren. Obwohl du recht hast; es ist sehr selten nützlich.((long)a - b)
hilft nicht, da Sie das Ergebnis zurücksetzen müssenint
, da dies der Vergleicher zurückgeben muss, was wiederum zu einem Überlauf führt. Sie müssten so etwas wieLong.signum
das Ergebnis tun , was leicht zu vergessen ist, wie Ihr Kommentar zeigt. Und es ist vielleicht nicht einmal effizienter als dasInteger.compare
, was die JVM an sich handhaben könnte ...Einfach ausgedrückt ist der
int
Typ nicht groß genug, um die Differenz zwischen zwei beliebigenint
Werten zu speichern . Beispielsweise beträgt die Differenz zwischen 1,5 und -1,5 Milliarden 3,0 Milliarden,int
kann jedoch keine Werte von mehr als 2,1 Milliarden enthalten.quelle
Vielleicht, um Überlauf / Unterlauf zu vermeiden.
quelle
Zusätzlich zum Überlauf sollten Sie beachten, dass die Version mit Subtraktion nicht die gleichen Ergebnisse liefert .
Wenn Sie wissen, dass es keinen Überlauf gibt, können Sie Folgendes verwenden:
public int compareTo(Integer anotherInteger) { return sign(this.value - anotherInteger.valuel); }
quelle
compareTo
ist nur erforderlich, um einen negativen Wert, Null oder einen positiven Wert zurückzugeben, abhängig von der Sortierreihenfolgethis
und dem anderen Objekt. Siehe java.sun.com/j2se/1.5.0/docs/api/java/lang/…