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

我有一个包含5个字段的Object Collection

 id; entityType; entityId; brandId; productId; 

要对CollectionArrayList进行排序,我编写了以下Comparaor

 Comparator collectionComparator = new Comparator() { @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的正确方法吗?

您的方法可能是正确的,但它效率低(不必要地调用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); } 

更好的方法是使用一种库方法,将所有这些逻辑抽象出来,这样你就不必考虑它了。 例如,使用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(); } 

首先, Collectionjava.util包中的一个类,所以将自己的类命名也可能不是最好的想法,尽管它当然是可能的。

其次,JDK8有一些简洁的方法来创建比较器,请查看: jdk8比较器

特别是第6和9节。

编辑:没有JKD8:

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