web-dev-qa-db-fra.com

Comment gérer les valeurs nulles lors de l'utilisation de Java tri de collection

Lorsque vous utilisez Collection.sort dans Java que dois-je retourner lorsque l'un des objets internes est nul

Exemple:

Collections.sort(list, new Comparator<MyBean>() {
    public int compare(MyBean o1, MyBean o2) {
      return o2.getDate().compareTo(o1.getDate());
     } 

});

Disons que o2 n'est pas nul mais o2.getDate (), alors dois-je retourner 1 ou -1 ou 0 lors de l'ajout d'une validation nulle?

31
Giancarlo Corzo

Naturellement, c'est votre choix. Quelle que soit la logique que vous écrivez, elle définira des règles de tri. Donc "devrait" n'est pas vraiment le bon mot ici.

Si vous voulez que null apparaisse avant tout autre élément, quelque chose comme ça pourrait faire

public int compare(MyBean o1, MyBean o2) {
    if (o1.getDate() == null) {
        return (o2.getDate() == null) ? 0 : -1;
    }
    if (o2.getDate() == null) {
        return 1;
    }
    return o2.getDate().compareTo(o1.getDate());
} 
40
Nikita Rybak

Dans Java 8, vous pouvez également utiliser nullsFirst():

Comparator.nullsFirst(Date::compareTo).compare(dateOne, dateTwo);

Ou nullsLast():

Comparator.nullsLast(Date::compareTo).compare(dateOne, dateTwo);

Ces méthodes trieront null au début ou à la fin. Il n'y a pas de mal ou de raison si vous considérez null plus ou moins grand qu'un autre objet. Cela dépend entièrement de vous, comme d'autres l'ont déjà dit.

21
user1438038

Cela dépend, considérez-vous null comme une grande valeur ou une valeur faible.

Vous pouvez considérer la plupart du temps que null <tout le reste, mais cela dépend du contexte.

Et 0 serait une terrible valeur de retour ici.

2
Colin Hebert

Suite à la réponse de Nikita Rybak, j'ai déjà un comparateur d'énumération et n'ajoute que la logique nulle d'ici.

public enum Orden implements Comparator<CmunParametrosDTO> {
        ByStrDescripcion {
            public int compare(CmunParametrosDTO item1, CmunParametrosDTO item2) {
                if (item1.getStrDescripcion() == null && item2.getStrDescripcion() == null)
                    return 0;
                if (item1.getStrDescripcion() == null)
                    return 1;
                else if (item2.getStrDescripcion() == null)
                    return -1;
                return item1.getStrDescripcion().compareTo(item2.getStrDescripcion());
            }
        }
        public abstract int compare(CmunParametrosDTO item1, CmunParametrosDTO item2);

        public Comparator<CmunParametrosDTO> ascending() {
            return this;
        }

        public Comparator<CmunParametrosDTO> descending() {
            return Collections.reverseOrder(this);
        }
}

Sous cette forme, je peux appeler la méthode de tri sur ma liste.

    if(isBolOrdAscendente()) Collections.sort(listado, CmunParametrosDTO.Orden.ByStrDescripcion .ascending());
    else Collections.sort(listado, CmunParametrosDTO.Orden.ByStrDescripcion .descending());
1
ELD

Selon que l'objet est nul ou que le contenu de l'objet est nul.

L'objet est nul:

    import static Java.util.Comparator.*;

    List<Data> listOfData = Arrays.asList(
           new Data("foo"),
           null,
           new Data("bar"),
           new Data("nyu"));

    listOfData.sort(nullsFirst(comparing(Data::getValue)));
    listOfData.forEach(System.out::println);
    //OUTPUT:
    // null
    // Data(bar)
    // Data(foo)
    // Data(nyu)

Le contenu de l'objet est nul:

    List<Data> listOfData = Arrays.asList(
           new Data("foo"),
           new Data(null),
           new Data("bar"),
           new Data("nyu"));


    listOfData.sort(nullsFirst(
         comparing(Data::getValue, nullsFirst(naturalOrder()))));

    listOfData.forEach(System.out::println);
    //OUTPUT:
    // Data(null)
    // Data(bar)
    // Data(foo)
    // Data(nyu)
0
davidddp