How to handle nulls when using Java collection sort

后端 未结 6 2067
离开以前
离开以前 2020-12-29 19:39

When using Collection.sort in Java what should I return when one of the inner objects is null

Example:

Collections.sort(list, new Comparator

        
相关标签:
6条回答
  • 2020-12-29 20:17

    if comparing two property, attr1 natural order, attr2 reverse order, and attr2 can be null:

    datas.sort(comparing(Data::getAttr1, naturalOrder()).
            thenComparing(Data::getAttr2, nullsLast(reverseOrder())));
    
    0 讨论(0)
  • 2020-12-29 20:20

    In Java 8 you can also use nullsFirst():

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

    Or nullsLast():

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

    These methods will either sort null to the beginning or to the end. There is no wrong or right whether you consider null bigger or smaller than another objects. This is totally up to you, as others stated already.

    0 讨论(0)
  • 2020-12-29 20:27

    Following the answer from Nikita Rybak, i'm already have a enum comparator, and only add the null logic from here.

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

    In this form i can call the sort method on my list.

        if(isBolOrdAscendente()) Collections.sort(listado, CmunParametrosDTO.Orden.ByStrDescripcion .ascending());
        else Collections.sort(listado, CmunParametrosDTO.Orden.ByStrDescripcion .descending());
    
    0 讨论(0)
  • 2020-12-29 20:30

    Naturally, it's your choice. Whatever logic you write, it will define sorting rules. So 'should' isn't really the right word here.

    If you want null to appear before any other element, something like this could do

    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());
    } 
    
    0 讨论(0)
  • 2020-12-29 20:36

    It depends, do you consider null as a big value or a low value.

    You can consider most of the time that null < everything else, but it depends on the context.

    And 0 would be a terrible return value here.

    0 讨论(0)
  • 2020-12-29 20:39

    Depending on whether the object is null, or the content of the object is null.

    The object is null:

        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)
    

    The content of the object is null:

        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 讨论(0)
提交回复
热议问题