35 votes

Contrat de Comparable et de Comparateur par rapport à null

Comparable le contrat précise que e.compareTo(null) doit jeter NullPointerException .

De l'API :

Notez que null n'est pas une instance d'une classe, et e.compareTo(null) devrait lancer un NullPointerException même si e.equals(null) renvoie à false .

D'un autre côté, Comparator API ne mentionne rien sur ce qui doit se passer lorsque l'on compare null . Considérez la tentative suivante d'une méthode générique qui prend un fichier Comparable et renvoie un Comparator pour celui qui met null comme élément minimal.

static <T extends Comparable<? super T>> Comparator<T> nullComparableComparator() {
   return new Comparator<T>() {
      @Override public int compare(T el1, T el2) {
         return
            el1 == null ? -1 :
            el2 == null ? +1 :
            el1.compareTo(el2);
      }
   };
}

Cela nous permet de faire ce qui suit :

List<Integer> numbers = new ArrayList<Integer>(
   Arrays.asList(3, 2, 1, null, null, 0)
);
Comparator<Integer> numbersComp = nullComparableComparator();
Collections.sort(numbers, numbersComp);
System.out.println(numbers);
// "[null, null, 0, 1, 2, 3]"

List<String> names = new ArrayList<String>(
   Arrays.asList("Bob", null, "Alice", "Carol")
);
Comparator<String> namesComp = nullComparableComparator();
Collections.sort(names, namesComp);
System.out.println(names);
// "[null, Alice, Bob, Carol]"

Les questions sont donc les suivantes :

  • Est-ce une utilisation acceptable d'un Comparator ou est-ce qu'il viole une règle non écrite concernant la comparaison de null et en jetant NullPointerException ?
  • Est-ce que c'est une bonne idée d'avoir à trier un List contenant null ou est-ce un signe certain d'une erreur de conception ?

25voto

cletus Points 276888

Comparable ne permet pas null simplement parce que :

a.compareTo(b) == -b.compareTo(a)

pour tous les objets a y b donde !a.equals(b) . Plus précisément :

a.equals(b) ? b.equals(a) && a.compareTo(b) == 0 &&
                  b.compareTo(a) == 0 && a.hashCode() == b.hashCode()
            : !b.equals(a) && a.compareTo(b) != 0 &&
                  a.compareTo(b) == -b.compareTo(a)

doit être évalué à true pour satisfaire aux contrats correspondants.

Alors null n'est pas autorisé parce que vous ne pouvez pas le faire :

null.compareTo(a)

Comparator est plus souple, de sorte que la gestion des null est un problème spécifique à l'implémentation. Soutenez-le ou non en fonction de ce que vous voulez que votre système de gestion de l'information soit Comparator à faire.

8voto

Est-ce une bonne idée de devoir trier une liste contenant des éléments nuls, ou est-ce le signe d'une erreur de conception ?

Conceptuellement, null signifie "rien", et ne rien placer dans une liste me semble bizarre. En outre, le contrat Java List stipule que

Certaines implémentations de listes ont des restrictions sur les éléments qu'elles peuvent contenir. Par exemple, certaines implémentations interdisent les éléments nuls.

Ainsi, la mise en œuvre d'une liste en Java n'est même pas tenue de prendre en charge les éléments nuls. En résumé, si vous n'avez pas de bonne raison de mettre des éléments nuls dans une liste, ne le faites pas, et si vous le faites, testez que cela fonctionne comme prévu.

4voto

camickr Points 137095

Est-ce que ce n'est jamais une bonne idée de devoir même trier une liste contenant des éléments nuls, ou est-ce un signe certain d'une erreur de conception de conception ?

Eh bien, cela n'a probablement pas de sens que la liste contienne un objet nul, mais peut-être que votre liste contient un "objet métier" et que vous pouvez trier sur différentes propriétés de l'objet métier, dont certaines peuvent contenir des nuls.

Est-ce une utilisation acceptable d'un Comparateur

Le site BeanComparator vous permet de trier sur une propriété dans un objet de gestion même si la propriété contient null, donc je dois dire que c'est une utilisation acceptable d'un 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