对嵌套对象执行 Collections.sort() 时如何处理空值?

How to handle null values when doing Collections.sort() with nested objects?

在对嵌套对象执行 Collections.sort() 时,处理 null 值的最佳方法是什么?

我想对几个对象进行排序,基本上应用此规则:

@Override
public int compare(final InvoicePos invoicePosOne, final InvoicePos invoicePosTwo) {
   return invoicePosOne.getInvoice().getInvoiceNo().compareTo(invoicePosTwo.getInvoice().getInvoiceNo());
}

但是,这些对象中的任何一个都可以是 null(即发票位置、发票和发票编号)。

public class InvoicePos {
  private Invoice invoice = null;

  // ...
}

public class Invoice {
  private String invoiceNo = "";

  // ...
}

我是否对我的所有对象进行了显式 null-检查,或者是否有一种更少写入的方法?


澄清一下:我知道我上面的例子可能会引发 NullPointerExceptions。目前我正在做以下事情,基本上,我问自己,是否有更聪明的方法。

     Collections.sort(allInvoicePositions, new Comparator<InvoicePos>() {
        @Override
        public int compare(final InvoicePos invoicePosOne, final InvoicePos invoicePosTwo) {
           if (null == invoicePosOne && null == invoicePosTwo) {
              return 0;
           }

           if (null == invoicePosOne) {
              return -1;
           }

           if (null == invoicePosTwo) {
              return 1;
           }

           if (null == invoicePosOne.getInvoice() && null == invoicePosTwo.getInvoice()) {
              return 0;
           }

           if (null == invoicePosOne.getInvoice()) {
              return -1;
           }

           if (null == invoicePosTwo.getInvoice()) {
              return 1;
           }

           if (null == invoicePosOne.getInvoice().getInvoiceNo() && null == invoicePosTwo.getInvoice().getInvoiceNo()) {
              return 0;
           }

           if (null == invoicePosOne.getInvoice().getInvoiceNo()) {
              return -1;
           }

           if (null == invoicePosTwo.getInvoice().getInvoiceNo()) {
              return 1;
           }

           return invoicePosOne.getInvoice().getInvoiceNo().compareTo(invoicePosTwo.getInvoice().getInvoiceNo());
        }
     });

Do I have do do explicit null-checks on all my objects or is there an approach with less writing?

如果这些值在您的 collection 中不代表任何内容,那么您能做的最好的事情就是避免使用它们;不允许插入它们,因此您在比较项目时不必处理它们。

如果您坚持要它们,那么您必须检查它们是否null以避免NullPointerException

如果您有空值,那么您需要以一致的方式明确地处理它们,以便拥有有效的排序关系。也就是说,类似于:

compare (a, b) {
  if (a == null && b == null) return 0;      
  if (a == null) return -1;
  if (b == null) return +1;
  return comp(a,b);
}

不要试图做这样的事情:

compare (a, b) {
  if (a == null || b == null) return -1;
  return comp(a,b);
}

这会破坏排序关系。

在 org.apache.commons.collections.jar 中有一个叫做 NullComparator 的东西。

这可能会对您有所帮助 https://commons.apache.org/proper/commons-collections/javadocs/api-2.1.1/org/apache/commons/collections/comparators/NullComparator.html