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

Java 如何忽略比较器中的空值?,java,comparator,Java,Comparator,我有一个比较器来比较对象的嵌套字段。这里是产品的价格 问题:如果该字段为null,则得到一个NullPointerException 问题:我如何告诉比较器忽略比较字段为空的对象,而不必事先过滤列表?对于忽略,我的意思是把它们放在列表的末尾 public class SorterTest { private static final Comparator<Product> PRODUCT_COMPARATOR = Comparator.comparin

我有一个比较器来比较对象的嵌套字段。这里是
产品的
价格

问题:如果该字段为null,则得到一个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;
    }
}

您可以使用比较器的nullsLast方法:

private static final Comparator PRODUCT_COMPARATOR = Comparator .nullsLast(Comparator.comparing(p -> p.details.price, Comparator.nullsLast(Comparator.naturalOrder()))); 专用静态最终比较器产品\u比较器= 比较器 .nullsLast(Comparator.comparing(p->p.details.price,Comparator.nullsLast(Comparator.naturalOrder()));
第一个nullslat表示产品为null,第二个表示价格为null。

您可以使用比较器的nullslat方法:

private static final Comparator PRODUCT_COMPARATOR = Comparator .nullsLast(Comparator.comparing(p -> p.details.price, Comparator.nullsLast(Comparator.naturalOrder()))); 专用静态最终比较器产品\u比较器= 比较器 .nullsLast(Comparator.comparing(p->p.details.price,Comparator.nullsLast(Comparator.naturalOrder()));
第一个nullslat表示产品为null,第二个表示价格为null。

由于价格为null,您会得到NullPointerException。因此,使用if语句检查价格值,如果为null,则使用其他值(如0)替换它。代码可能类似于:

public class SorterTest {
    private static final Comparator<Product> PRODUCT_COMPARATOR =
            Comparator.comparing(p->
                    {
                        if (p.details != null && p.details.price != null) {
                            return p.details.price;
                        } else {
                            return new BigDecimal(0);
                        }
                    }
            );

    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("D", products.get(0).name);
        assertEquals("E", products.get(1).name);
        assertEquals("F", products.get(2).name);
        assertEquals("C", products.get(3).name);
        assertEquals("A", products.get(4).name);
        assertEquals("B", 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;
    }
}
public class SorterTest{
专用静态最终比较器产品比较器=
比较器。比较(p->
{
if(p.details!=null&&p.details.price!=null){
返回p.details.price;
}否则{
返回新的BigDecimal(0);
}
}
);
静态类积{
字符串名;
细节;
静态类详细信息{
大十进制价格;
}
}
@试验
公开无效测试(){
List products=Arrays.asList(
createProduct(“A”,新的BigDecimal(30.00)),
createProduct(“B”,新的BigDecimal(55.00)),
createProduct(“C”,新的BigDecimal(20.00)),
createProduct(“D”,空),
createProduct(“E”,空),
createProduct(“F”,空)
);
集合。排序(产品、产品和比较器);
assertEquals(“D”,products.get(0.name));
assertEquals(“E”,products.get(1.name));
assertEquals(“F”,products.get(2.name));
assertEquals(“C”,products.get(3.name));
assertEquals(“A”,products.get(4.name));
assertEquals(“B”,products.get(5.name));
}
私有产品createProduct(字符串名称,BigDecimal价格){
产品p=新产品();
p、 详细信息=新产品。详细信息();
p、 名称=名称;
p、 details.price=价格;
返回p;
}
}

由于价格为空,因此您会得到NullPointerException。因此,使用if语句检查价格值,如果为null,则使用其他值(如0)替换它。代码可能类似于:

public class SorterTest {
    private static final Comparator<Product> PRODUCT_COMPARATOR =
            Comparator.comparing(p->
                    {
                        if (p.details != null && p.details.price != null) {
                            return p.details.price;
                        } else {
                            return new BigDecimal(0);
                        }
                    }
            );

    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("D", products.get(0).name);
        assertEquals("E", products.get(1).name);
        assertEquals("F", products.get(2).name);
        assertEquals("C", products.get(3).name);
        assertEquals("A", products.get(4).name);
        assertEquals("B", 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;
    }
}
public class SorterTest{
专用静态最终比较器产品比较器=
比较器。比较(p->
{
if(p.details!=null&&p.details.price!=null){
返回p.details.price;
}否则{
返回新的BigDecimal(0);
}
}
);
静态类积{
字符串名;
细节;
静态类详细信息{
大十进制价格;
}
}
@试验
公开无效测试(){
List products=Arrays.asList(
createProduct(“A”,新的BigDecimal(30.00)),
createProduct(“B”,新的BigDecimal(55.00)),
createProduct(“C”,新的BigDecimal(20.00)),
createProduct(“D”,空),
createProduct(“E”,空),
createProduct(“F”,空)
);
集合。排序(产品、产品和比较器);
assertEquals(“D”,products.get(0.name));
assertEquals(“E”,products.get(1.name));
assertEquals(“F”,products.get(2.name));
assertEquals(“C”,products.get(3.name));
assertEquals(“A”,products.get(4.name));
assertEquals(“B”,products.get(5.name));
}
私有产品createProduct(字符串名称,BigDecimal价格){
产品p=新产品();
p、 详细信息=新产品。详细信息();
p、 名称=名称;
p、 details.price=价格;
返回p;
}
}
您可以使用Optional查看getter的结果是空值还是有效值。对于空值,您可以通过始终将它们的comparator()结果处理为-1或1,将它们放在尾部或头部

private static final Comparator<Product> PRODUCT_COMPARATOR = 
           Comparator.comparing(p -> {
               Optional<BigDecimal> res = Optional.ofNullable(p.getPrice);
               if(res.isPresent())
                   return p.getPrice();
               else
                   return -1;
           });
           ...
static class Product {
        String name;
        BigDecimal price;

        BigDecimal getPrice(){
            return this.price;
        }
        ...
}
专用静态最终比较器产品\u比较器=
比较器。比较(p->{
可选资源=可选的可用资源(p.getPrice);
if(res.isPresent())
返回p.getPrice();
其他的
返回-1;
});
...
静态类积{
字符串名;
大十进制价格;
BigDecimal getPrice(){
退回这个价格;
}
...
}
您可以使用Optional查看getter的结果是空值还是有效值。对于空值,您可以通过始终将它们的comparator()结果处理为-1或1,将它们放在尾部或头部

private static final Comparator<Product> PRODUCT_COMPARATOR = 
           Comparator.comparing(p -> {
               Optional<BigDecimal> res = Optional.ofNullable(p.getPrice);
               if(res.isPresent())
                   return p.getPrice();
               else
                   return -1;
           });
           ...
static class Product {
        String name;
        BigDecimal price;

        BigDecimal getPrice(){
            return this.price;
        }
        ...
}
专用静态最终比较器产品\u比较器=
比较器。比较(p->{
可选资源=可选的可用资源(p.getPrice);
if(res.isPresent())
返回p.getPrice();
其他的
返回-1;
});
...
静态类积{
字符串名;
大十进制价格;
BigDecimal getPrice(){
退回这个价格;
}
...
}
?您必须决定<