如何在使用Java集合排序时处理空值

时间:2010-09-08 20:54:51

标签: java sorting collections nullpointerexception

在Java中使用Collection.sort时,当其中一个内部对象为null时,我应该返回什么

示例:

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

});

让我们说o2不是null但是它是o2.getDate(),所以在添加空验证时我应该返回1还是-1还是0?

6 个答案:

答案 0 :(得分:36)

当然,这是你的选择。无论你写什么逻辑,它都会定义排序规则。所以'应该'在这里不是正确的词。

如果你想让null出现在任何其他元素之前,可以这样做

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

答案 1 :(得分:18)

在Java 8中,您还可以使用nullsFirst()

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

nullsLast()

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

这些方法会将null排序到开头或结尾。您是否认为null比其他对象更大或更小没有错误或正确。这完全取决于你,正如其他人所说的那样。

答案 2 :(得分:2)

这取决于,你认为null是一个大值还是一个低值。

你可以在大多数时候考虑null&lt;其他一切,但这取决于背景。

0这将是一个可怕的回报值。

答案 3 :(得分:1)

根据Nikita Rybak的回答,我已经有了一个枚举比较器,只能从这里添加空逻辑。

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

在这种形式中,我可以在我的列表中调用sort方法。

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

答案 4 :(得分:1)

取决于对象是空还是对象的内容为空。

该对象为空:

    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)

对象的内容为空:

    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)

答案 5 :(得分:0)

如果比较两个属性,即attr1自然顺序,attr2反向顺序和 attr2可以为空:

datas.sort(comparing(Data::getAttr1, naturalOrder()).
        thenComparing(Data::getAttr2, nullsLast(reverseOrder())));