148 votes

Pourquoi n ' t impossible implémenter Comparable ?

Personne ne sait pourquoi java.lang.Number ne met pas en oeuvre Comparable? Cela signifie que vous ne pouvez pas trier Numbers avec Collections.sort ce qui me semble un peu étrange.

Post de discussion mise à jour:

Merci pour toutes les réponses utiles. J'ai fini par faire un peu plus de recherche sur ce sujet.

L'explication la plus simple pour expliquer pourquoi java.lang.Le numéro n'est pas de mettre en œuvre Comparable est enracinée dans la mutabilité des préoccupations.

Un peu de révision, java.lang.Number le résumé est-il super-type d' AtomicInteger, AtomicLong, BigDecimal, BigInteger, Byte, Double, Float, Integer, Long et Short. Sur cette liste, AtomicInteger et AtomicLong à ne pas mettre en oeuvre Comparable.

Creuser autour, j'ai découvert que ce n'est pas une bonne pratique à mettre en œuvre Comparable sur mutable types parce que les objets peuvent changer au cours de ou après comparaison rendu le résultat de la comparaison inutile. Les deux AtomicLong et AtomicInteger sont mutables. Les API ont eu la prévoyance de ne pas avoir Number œuvre Comparable , parce qu'il aurait contraint la mise en œuvre des futurs sous-types. En effet, AtomicLong et AtomicInteger ont été ajoutés dans Java 1.5 longtemps après, java.lang.Number a été initialement mise en œuvre.

En dehors de la mutabilité, il y a probablement d'autres considérations trop. Un compareTo mise en œuvre en Number aurait pour promouvoir toutes les valeurs numériques à l' BigDecimal parce qu'il est capable d'accueillir tous les Number sous-types. L'implication de cette promotion en termes de mathématiques et de la performance est un peu claire pour moi, mais mon intuition constate que la solution encombrants.

75voto

cletus Points 276888

Il est important de mentionner que l'expression suivante:

new Long(10).equals(new Integer(10))

est toujours false, ce qui tend à voyage de tout le monde, à un moment ou à un autre. Ainsi, non seulement vous pouvez pas comparer arbitraire Numbers, mais vous ne pouvez même pas de déterminer si elles sont égales ou non.

Aussi, avec les vrais types primitifs (float, double), de déterminer si deux valeurs sont égales est délicate et doit être fait à l'intérieur d'une marge d'erreur acceptable. Essayez de code comme:

double d1 = 1.0d;
double d2 = 0.0d;
for (int i=0; i<10; i++) {
  d2 += 0.1d;
}
System.out.println(d2 - d1);

et vous serez à gauche avec une petite différence.

Donc, pour revenir à la question de la prise de Number Comparable. Comment voulez-vous mettre en œuvre? En utilisant quelque chose comme doubleValue() ne serait pas le faire de manière fiable. Rappelez-vous l' Number sous-types sont:

  • Byte;
  • Short;
  • Integer;
  • Long;
  • AtomicInteger;
  • AtomicLong;
  • Float;
  • Double;
  • BigInteger; et
  • BigDecimal.

Pourriez-vous code fiable compareTo() méthode qui n'a pas dégénérer en une série de si instanceof déclarations? Number cas seulement six méthodes à leur disposition:

  • byteValue();
  • shortValue();
  • intValue();
  • longValue();
  • floatValue(); et
  • doubleValue().

Donc je suppose que le Soleil fait le (raisonnable) de la décision qu' Numbers ont été seulement Comparable aux instances d'eux-mêmes.

46voto

Eddie Points 27755

Pour la réponse, voir Java bugparade bug 4414323. Vous pouvez également trouver une discussion de comp.lang.java.programmeur

Pour citer le Soleil de réponse pour le rapport de bug à partir de 2001:

Tous les "chiffres" ne sont pas comparables; comparable suppose un total de commande de numéros est possible. Ce n'est pas le même vrai pour les nombres à virgule flottante; NaN (pas un nombre) n'est ni moins, plus grand que, ni la même pour tout valeur à virgule flottante, même de lui-même. {Float, Double}.comparer imposer un total la commande différente de la commande de la virgule flottante "<" et "=" des opérateurs. En outre, comme actuellement mis en œuvre, les sous-classes de Nombre ne sont comparables à d'autres instances de la même classe. Il y a d'autres cas, comme celui des nombres complexes, où aucun standard total de la commande existe, bien que l'on puisse être défini. Dans bref, si oui ou non une sous-classe de Nombre est comparable devrait être laissé tel une décision pour que la sous-classe.

Note pour celui qui downvoted ceci: je ne dis pas que c'est la bonne réponse qui devrait faire le bonheur de tous. Je dis juste que c'est le Soleil de la réponse. Ils définissent actuellement la "marque" de sorte que leur réponse est sans appel, qu'on le veuille ou non. C'est pourquoi je l'ai lié à la poursuite de la discussion.

5voto

z - Points 5610

afin de mettre en œuvre comparables sur le nombre, vous devrez écrire du code pour chaque paire de sous-classe. C’est plus facile au contraire permettre juste sous-classes implémenter comparable.

3voto

Pete Kirkham Points 32484

Très probablement parce que ce serait plutôt inefficace pour comparer les nombres - la seule représentation dans laquelle chaque nombre peut s’adapter pour permettre une telle comparaison serait BigDecimal.

Au lieu de cela, les sous-classes non atomiques de nombre implémente Comparable lui-même.

Atomiques sont mutables, donc ne peut pas implémenter une comparaison atomique.

2voto

Hilmar Points 21

Écrivez votre propre comparateur

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X