具有多个字段的对象的 Java 比较器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23981199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Comparator for Objects with multiple fields
提问by Tapas Bose
I have an Object Collection
with 5 fields:
我有一个Collection
包含 5 个字段的对象:
id;
entityType;
entityId;
brandId;
productId;
To sort an ArrayList
of Collection
I have written the following Comparaor
.
为了排序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());
}
};
Is this the right way to implement Comparator
on the object which has multiple fields to compare?
这是Comparator
在具有多个字段进行比较的对象上实现的正确方法吗?
采纳答案by MikeFHay
Your method might be correct, but it is inefficient (unnecessarily calls equals) and difficult to read. It could be rewritten something like this:
您的方法可能是正确的,但效率低下(不必要地调用 equals)并且难以阅读。可以这样改写:
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
更好的是使用一个库方法来抽象所有这些逻辑,这样你就不必考虑它了。例如使用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();
}
回答by kajacx
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.
首先,Collection
是一个来自java.util
包的类,所以命名你自己的类可能不是最好的主意Collection
,尽管这当然是可能的。
Second, JDK8 have some neat ways to create comparators, check here: jdk8 comparators
其次,JDK8 有一些巧妙的方法来创建比较器,请查看这里:jdk8比较器
Esspecially section 6 and 9.
特别是第 6 和 9 节。
EDIT: Without JKD8:
编辑:没有 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.
当通过 5 个不同的属性进行比较时,我不会像这样对比较进行硬编码,您始终可以创建自己的比较器链接器(类似于上一个链接中的第 9 点)并将 5 个单独的比较器链接在一起。