如何编写通用比较器,可以对所有必要的字段进行排序?

我需要在我class级的所有领域实现排序,我为class上的每个领域编写了一个比较器。 但我必须为每个字段编写一个单独的比较器。 我认为这不是很正确。 如何为我的class级写一个通用比较器,可以对所有领域进行排序?

我的实体:

public class User { private long id; private String name; private int age; ..................... 

我的比较器:

 public class UserComparatorById implements Comparator { public int compare(User user1, User user2) { int result = (int)(user1.getId() - user2.getId()); if (result != 0) return (int)(result/Math.abs(result)); result = user1.getName().compareTo (user2.getName()); if (result != 0) return (int)(result/Math.abs(result)); result = user1.getAge() - user2.getAge(); return (result != 0) ? (int)(result/Math.abs(result)) : 0; } } 

 public class UserComparatorByName implements Comparator { public int compare(User user1, User user2) { int result = user1.getName().compareTo (user2.getName()); if (result != 0) return (int)(result/Math.abs(result)); result = (int)(user1.getId() - user2.getId()); if (result != 0) return (int)(result/Math.abs(result)); result = user1.getAge() - user2.getAge(); return (result != 0) ? (int)(result/Math.abs(result)) : 0; } } 

 public class UserComparatorByAge implements Comparator { public int compare(User user1, User user2) { int result = user1.getAge() - user2.getAge(); if (result != 0) return (int)(result/Math.abs(result)); result = (int)(user1.getId() - user2.getId()); if (result != 0) return (int)(result/Math.abs(result)); result = user1.getName().compareTo (user2.getName()); return (result != 0) ? (int)(result/Math.abs(result)) : 0; } } 

排序:

 List users = new ArrayList(); users.add(new User(5, "Frank", 28)); users.add(new User(1, "Jorge", 19)); users.add(new User(6, "Bill", 34)); users.add(new User(3, "Michel", 17)); users.add(new User(7, "Mark", 42)); UserComparatorByName comparatorByName = new UserComparatorByName(); Collections.sort(users, comparatorByName); UserComparatorByAge comparatorByAge = new UserComparatorByAge(); Collections.sort(users, comparatorByAge); 

每个字段的一个实现并不是那么糟糕,但是代码中存在大量重复。 每个字段应该有一个比较器。 如果要基于多个字段进行比较,但顺序不同,请包装primefaces比较器( 装饰器模式):

 public abstract class AbstractComparator implements Comparator { private final AbstractComparator next; public AbstractComparator(AbstractComparator next) { this.next = next; } public int compare(User user1, User user2) { int result = doCompare(user1, user2); if (result != 0) { return result; } else { return next != null? next.compare(user1, user2) : 0; } } public abstract int doCompare(User user1, User user2); } 

 class ById extends AbstractComparator { public ById(AbstractComparator next) { super(next); } public int doCompare(User user1, User user2) { return (int) (user1.getId() - user2.getId()); } } 

 class ByName extends AbstractComparator { public ByName(AbstractComparator next) { super(next); } public int doCompare(User user1, User user2) { return user1.getName().compareTo(user2.getName()); } } 

 class ByAge extends AbstractComparator { public ByAge(AbstractComparator next) { super(next); } public int doCompare(User user1, User user2) { return user1.getAge() - user2.getAge(); } } 

用法:

 Comparator comp1 = new ById(new ByName(new ByAge(null))); Comparator comp2 = new ByAge(new ByName(new ById(null))); 

comp1首先按id排序,如果它相等,则回退到name并作为最后的手段进行age 。 API很清楚。

为方便起见,您应将所有By*类作为User静态内部类: User.ByNameUser.ByAge等,或者使用一些工厂方法: User.byName(User.byAge(null)) 。 在一些静态导入的帮助下,您可以获得愉快的:

 Collections.sort(users, byName(byAge(byId(null)))); 

或者看看Commons Lang的CompareToBuilder 。

也许Bean Comparator和Group Comparator会帮助你。