Java Integer compareTo() - pourquoi utiliser la comparaison vs. soustraction?
j'ai trouvé que java.lang.Integer
mise en œuvre de compareTo
méthode ressemble à ce qui suit:
public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
la question Est de savoir pourquoi utiliser la comparaison au lieu de la soustraction:
return thisVal - anotherVal;
5 réponses
ceci est dû à un débordement d'entier. Lorsque thisVal
est très grand et que anotherVal
est négatif, la soustraction de ce dernier produit un résultat qui est plus grand que thisVal
qui peut déborder à la gamme négative.
le" truc " de soustraction pour comparer deux valeurs numériques est cassé!!!
int a = -2000000000;
int b = 2000000000;
System.out.println(a - b);
// prints "294967296"
ici, a < b
, pourtant a - b
est positif.
N'utilisez pas cet idiome. Il ne fonctionne pas.
de plus, même s'il fonctionne , il sera pas fournir toute amélioration significative dans la performance, et peut en fait coût lisibilité.
voir aussi
- Java casse-têtes Puzzle de 65 ans: Une Étrange Saga des Suspects de Tri
ce puzzle a plusieurs leçons. Le plus spécifique est: N'utilisez pas un comparateur basé sur la soustraction à moins que vous ne soyez sûr que la différence entre les valeurs ne sera jamais plus grande que
Integer.MAX_VALUE
. Plus généralement, méfiez-vous du débordement deint
. Une autre leçon est que vous devriez éviter le code" intelligent". S'efforcer d'écrire un code clair et correct, et ne pas l'optimiser à moins qu'il ne s'avère nécessaire.
pour parler simplement, le type int
n'est pas assez grand pour stocker la différence entre deux valeurs int
arbitraires. Par exemple, la différence entre 1,5 milliards et -1,5 milliards est de 3,0 milliards, mais int
ne peut pas détenir des valeurs supérieures à 2,1 milliards.
C'est peut-être pour éviter les débordements / sous-écoulements.
en plus de la chose de débordement, vous devriez noter que la version avec la soustraction ne donne pas les mêmes résultats .
- la première version de compareTo renvoie une des trois valeurs possibles: -1, 0, ou 1.
- si vous remplacez la dernière ligne par soustraction, le résultat peut être n'importe quelle valeur entière.
si vous savez qu'il n'y aura pas de débordement, vous pouvez utiliser quelque chose comme ceci:
public int compareTo(Integer anotherInteger) {
return sign(this.value - anotherInteger.valuel);
}