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);
}