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;
76
demandé sur jahroy 2010-04-28 14:59:44

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.

86
répondu Itay Maman 2013-02-06 10:29:25

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 de int . 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.

61
répondu polygenelubricants 2010-04-28 11:09:28

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.

9
répondu fredoverflow 2010-04-28 12:03:59

C'est peut-être pour éviter les débordements / sous-écoulements.

3
répondu Adamski 2010-04-28 11:02:49

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);
}
1
répondu PauliL 2010-04-28 13:23:07