比较器:将2个对象与可以为空的字段进行比较

时间:2018-04-25 12:18:17

标签: java lambda comparator comparable

我需要通过实现默认比较器的典型比较方法来编写null。这是由于我需要实现的接口而给出的。

我的对象是Comparator字段Integer的产品,可以是vintage。代码如下:

null

我对此并不满意,因为我有很多重复的代码,我确信有更好的方法可以做到这一点......任何建议都会受到赞赏。

5 个答案:

答案 0 :(得分:3)

Comparator换入Comparator.nullsFirst以避免处理可能null个参数。

您需要与Comparator合并两个Comparator#thenComparing

  1. nullsFirst(naturalOrder())首先比较IProduct;
  2. nullsFirst(comparing(p -> p...getVintage())来比较他们的Vintage

    Comparator<IProduct> comparator =
        nullsFirst(Comparator.<IProduct>naturalOrder())
            .thenComparing(nullsFirst(
                comparing(p -> p.getProvidedProductData().getVintage())
            )
        );
    
  3. 这种方法自然地比较了IProduct您显然不想做的事情。 (你根本没有比较它们。)

    然后,您可以写IProduct p1, IProduct p2) -> 0以在两个Vintage都不是IProduct之后继续比较null

     Comparator<IProduct> comparator =
            nullsFirst((IProduct p1, IProduct p2) -> 0)
                .thenComparing(nullsFirst(
                     comparing(p -> p.getProvidedProductData().getVintage())
                )
            );
    

    如果getVintage返回int,您可以使用Comparator.comparingInt代替Comparator.comparing

    comparingInt(p -> p.getProvidedProductData().getVintage())
    

答案 1 :(得分:2)

简单地使用(我假设您使用 lambda 标记了问题,因此您使用的是Java8 +) 来自Comparator的以下任一方法:

public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator)
public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator)

答案 2 :(得分:1)

您可以使用Java 8中引入的Comparator方法并使用方法引用,例如:

Comparator.comparing(IProductData::getVintage, Comparator.nullsLast(Comparator.naturalOrder()))

答案 3 :(得分:1)

这个怎么样?:

Comparator<IProduct> comparator = (p1, p2) -> {
    Integer v1 = p1 != null ? p1.getProvidedProductData() : null;
    Integer v2 = p2 != null ? p2.getProvidedProductData() : null;

    if (v1 == null ^ v2 == null)
        return v1 != null ? 1 : -1;

    return v1 != null ? v1.compareTo(v2) : 0;
};

答案 4 :(得分:0)

一种可能性是推广空检查。

public int compare(IProduct product1, IProduct product2) throws ProductComparisonException {
    Integer diff = nullCompare(product1, product2);
    if(diff != null) return diff;

    IProductData productData1 = (IProductData)product1.getProvidedProductData();
    IProductData productData2 = (IProductData)product2.getProvidedProductData();

    diff = nullCompare(productData1.getVintage(), productData2.getVintage());
    if(diff != null) return diff;

    return productData2.getVintage().compareTo(productData2.getVintage());
}

// Using Integer so I can return `null`.
private Integer nullCompare(Object o1, Object o2) {
    if (o1 == null && o2 == null) {
        return 0;
    }
    else if (o1 == null && o2 != null) {
        return -1;
    }
    else if (o1 != null && o2 == null) {
        return 1;
    }
    return null;
}