我有一个包含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
的正确方法吗?
答案 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个独立的比较器。