Frage Java Integer compareTo () - Warum Vergleich gegen Subtraktion verwenden?


Ich habe das gefunden java.lang.Integer Implementierung von compareTo Methode sieht folgendermaßen aus:

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 verwenden:

return thisVal - anotherVal;

76
2018-04-28 10:59


Ursprung


Antworten:


Dies liegt an Integer-Überlauf. Wann thisVal ist sehr groß und anotherVal ist negativ, dann subtrahiert das letztere von dem ersteren ein Ergebnis, das größer als ist thisVal die in den negativen Bereich überlaufen kann.


85
2018-04-28 11:02



Die Subtraktion "Trick", um zwei Zahlenwerte zu vergleichen, ist gebrochen !!!

        int a = -2000000000;
        int b =  2000000000;
        System.out.println(a - b);
        // prints "294967296"

Hier, a < b, noch a - b ist positiv.

Verwenden Sie dieses Idiom NICHT. Es funktioniert nicht.

Außerdem, auch wenn es funktioniert, es wird NICHT eine signifikante Verbesserung der Leistung bieten und tatsächlich die Lesbarkeit kosten kann.

Siehe auch

  • Java Puzzler Puzzle 65: Eine seltsame Saga der verdächtigen Sort

    Dieses Puzzle hat mehrere Lektionen. Das spezifischste ist: Verwenden Sie keinen subtraktionsbasierten Vergleicher, wenn Sie nicht sicher sind, dass der Unterschied zwischen den Werten niemals größer als sein wird  Integer.MAX_VALUE. Im Allgemeinen, Vorsicht vor int Überlauf. Eine andere Lektion ist, dass Sie "cleveren" Code vermeiden sollten. Bemühen Sie sich, klaren, korrekten Code zu schreiben, und optimieren Sie ihn nicht, es sei denn, es erweist sich als notwendig.


60
2018-04-28 11:09



Einfach gesagt, die int Typ ist nicht groß genug, um den Unterschied zwischen zwei beliebigen zu speichern int Werte. Zum Beispiel ist die Differenz zwischen 1,5 Milliarden und -1,5 Milliarden 3,0 Milliarden, aber int kann Werte von mehr als 2,1 Milliarden nicht halten.


9
2018-04-28 12:03



Vielleicht ist es, Überlauf / Unterlauf zu vermeiden.


3
2018-04-28 11:02



Neben der Überlauf-Sache sollten Sie beachten, dass die Version mit Subtraktion gibt nicht die gleichen Ergebnisse.

  • Die erste compareTo-Version gibt einen von drei möglichen Werten zurück: -1, 0 oder 1.
  • Wenn Sie die letzte Zeile durch Subtraktion ersetzen, kann das Ergebnis ein beliebiger ganzzahliger Wert sein.

Wenn Sie wissen, dass es keinen Überlauf geben wird, können Sie Folgendes verwenden:

public int compareTo(Integer anotherInteger) {
    return sign(this.value - anotherInteger.valuel);
}

1
2018-04-28 13:23