我需要在我班级的所有领域实现排序,我为班上的每个领域编写了一个比较器.但我必须为每个字段编写一个单独的比较器.我认为这不是很正确.如何为我的班级编写一个可以对所有字段进行排序的通用比较器?
我的实体:
public class User {
private long id;
private String name;
private int age;
.....................
Run Code Online (Sandbox Code Playgroud)
我的比较器:
public class UserComparatorById implements Comparator<User> {
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;
}
}
Run Code Online (Sandbox Code Playgroud)
public class UserComparatorByName implements Comparator<User> {
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;
}
}
Run Code Online (Sandbox Code Playgroud)
public class UserComparatorByAge implements Comparator<User> {
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;
}
}
Run Code Online (Sandbox Code Playgroud)
排序:
List<User> users = new ArrayList<User>();
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);
Run Code Online (Sandbox Code Playgroud)
每个字段的一个实现并不是那么糟糕,但是代码中存在大量重复.每个字段应该有一个比较器.如果要基于多个字段进行比较,但顺序不同,请包装原子比较器(装饰器模式):
public abstract class AbstractComparator implements Comparator<User> {
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);
}
Run Code Online (Sandbox Code Playgroud)
class ById extends AbstractComparator {
public ById(AbstractComparator next) {
super(next);
}
public int doCompare(User user1, User user2) {
return (int) (user1.getId() - user2.getId());
}
}
Run Code Online (Sandbox Code Playgroud)
class ByName extends AbstractComparator {
public ByName(AbstractComparator next) {
super(next);
}
public int doCompare(User user1, User user2) {
return user1.getName().compareTo(user2.getName());
}
}
Run Code Online (Sandbox Code Playgroud)
class ByAge extends AbstractComparator {
public ByAge(AbstractComparator next) {
super(next);
}
public int doCompare(User user1, User user2) {
return user1.getAge() - user2.getAge();
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
Comparator<User> comp1 = new ById(new ByName(new ByAge(null)));
Comparator<User> comp2 = new ByAge(new ByName(new ById(null)));
Run Code Online (Sandbox Code Playgroud)
comp1首先通过排序id,如果相等,回落到name并age作为最后的手段.API很清楚.
为方便起见,你应该把所有By*类的静态内部类User:User.ByName,User.ByAge,等,或可能与一些工厂方法:User.byName(User.byAge(null)).在一些静态导入的帮助下,您可以获得愉快的:
Collections.sort(users, byName(byAge(byId(null))));
Run Code Online (Sandbox Code Playgroud)
或者看看Commons Lang的CompareToBuilder.
| 归档时间: |
|
| 查看次数: |
2013 次 |
| 最近记录: |