具有多个字段的对象的Java Comparator

时间:2014-06-01 15:05:54

标签: java sorting object comparator

我有一个包含5个字段的对象Collection

id;
entityType;
entityId;
brandId;
productId;

要对ArrayList Collection进行排序,我写了以下Comparaor

Comparator<Collection> collectionComparator = new Comparator<Collection>() {

    @Override
    public int compare(Collection collection1, Collection collection2) {
        if(collection1.getId().equals(collection2.getId())) {
            if(collection1.getEntityType().equals(collection2.getEntityType())) {
                if(collection1.getEntityId().equals(collection2.getEntityId())) {
                    if(collection1.getBrandId().equals(collection2.getBrandId())) {
                        return collection1.getProductId().compareTo(collection2.getProductId());
                    } else {
                        return collection1.getBrandId().compareTo(collection2.getBrandId());
                    }
                } else {
                    return collection1.getEntityId().compareTo(collection2.getEntityId());
                }
            } else {
                return collection1.getEntityType().compareTo(collection2.getEntityType());
            }
        } 

        return collection1.getId().compareTo(collection2.getId());
    }
};

这是在具有多个要比较的字段的对象上实现Comparator的正确方法吗?

2 个答案:

答案 0 :(得分:6)

您的方法可能是正确的,但效率低(不必要地调用等于)并且难以阅读。它可以改写成这样的东西:

public int compare(Collection c1, Collection c2)
{
    int n;
    n = c1.id.compareTo(c2.id);
    if (n != 0) return n;
    n = c1.entityType.compareTo(c2.entityType);
    if (n != 0) return n;
    n = c1.brandId.compareTo(c2.brandId);
    if (n != 0) return n;
    return c1.productId.compareTo(c2.productId);
}

更好的方法是使用一种库方法,将所有这些逻辑抽象出来,这样你就不必考虑它了。例如。使用apache.commons.lang CompareToBuilder

public int compare(Collection c1, Collection c2)
{
    return new CompareToBuilder()
            .append(c1.id, c2.id)
            .append(c1.entityType, c2.entityType)
            .append(c1.brandId, c2.brandId)
            .append(c1.productId, c2.productId)
            .toComparison();
}

答案 1 :(得分:0)

首先,Collection是来自java.util包的一个类,所以将自己的类命名为Collection可能不是最佳选择,尽管它当然是可能的。

其次,JDK8有一些简洁的方法来创建比较器,请点击此处:jdk8 comparators

特别是第6和第9节。

编辑:没有JKD8:

当比较5个不同的属性时,我不会像这样硬编码比较,你总是可以创建自己的比较器链接器(类似于前一个链接中的第9点)和链接5个独立的比较器。