Java Comparator for Objects with multiple fields [closed]

狂风中的少年 提交于 2019-12-19 05:10:35

问题


I have an Object Collection with 5 fields:

id;
entityType;
entityId;
brandId;
productId;

To sort an ArrayList of Collection I have written the following 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());
    }
};

Is this the right way to implement Comparator on the object which has multiple fields to compare?


回答1:


Your method might be correct, but it is inefficient (unnecessarily calls equals) and difficult to read. It could be rewritten something like this:

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);
}

Even better is to use a library method which abstracts all this logic away so you don't have to think about it. E.g. using 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();
}



回答2:


First, Collection is a class from java.util package, so it's probably not the best idea to name your own class Collection too, although it is certainly possible.

Second, JDK8 have some neat ways to create comparators, check here: jdk8 comparators

Esspecially section 6 and 9.

EDIT: Without JKD8:

When comparing by 5 different attributes, I wouldn't hardcode the comparasion like that, you can always create your own comparator chainer (something like point 9 from previous link) and chain 5 separate comparators together.



来源:https://stackoverflow.com/questions/23981199/java-comparator-for-objects-with-multiple-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!