如何忽略比较器中的空值?

mem*_*und 1 java comparator

我有一个比较对象的嵌套字段的比较器。这里的pricea product

问题:如果该字段为空,我将收到 NullPointerException。

问题:如何告诉比较器忽略比较字段为空的对象,而无需(!)事先过滤列表?忽略我的意思是将它们放在列表的末尾。

public class SorterTest {
    private static final Comparator<Product> PRODUCT_COMPARATOR = 
           Comparator.comparing(p -> p.details.price);

    static class Product {
        String name;
        Details details;

        static class Details {
            BigDecimal price;
        }
    }

    @Test
    public void test() {
        List<Product> products = Arrays.asList(
                createProduct("A", new BigDecimal(30.00)),
                createProduct("B", new BigDecimal(55.00)),
                createProduct("C", new BigDecimal(20.00)),
                createProduct("D", null),
                createProduct("E", null),
                createProduct("F", null)
        );

        Collections.sort(products, PRODUCT_COMPARATOR);
        assertEquals("C", products.get(0).name);
        assertEquals("A", products.get(1).name);
        assertEquals("B", products.get(2).name);
        assertEquals("D", products.get(3).name);
        assertEquals("E", products.get(4).name);
        assertEquals("F", products.get(5).name);
    }

    private Product createProduct(String name, BigDecimal price) {
        Product p = new Product();
        p.details = new Product.Details();
        p.name = name;
        p.details.price = price;
        return p;
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

java.lang.NullPointerException
    at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469)
    at java.util.TimSort.binarySort(TimSort.java:296)
    at java.util.TimSort.sort(TimSort.java:221)
    at java.util.Arrays.sort(Arrays.java:1438)
    at java.util.Arrays$ArrayList.sort(Arrays.java:3895)
    at java.util.Collections.sort(Collections.java:175)
Run Code Online (Sandbox Code Playgroud)

Uwe*_*ner 6

您可以使用 Comparator 的 nullsLast 方法:

   私有静态最终比较器 PRODUCT_COMPARATOR = 
           比较器
           .nu​​llsLast(Comparator.comparing(p -> p.details.price, Comparator.nullsLast(Comparator.naturalOrder())));

Product 的第一个 nullsLast 为 null,而 price 的第二个 nullsLast 为 null。