我有一个名为Person
的类,它有多个属性,例如:
public class Person {
private int id;
private String name, address;
// Many more properties.
}
很多Person
-objects都存储在ArrayList<Person>
中。我希望通过多个排序参数对此列表进行排序,并且有时会有所不同。例如,我可能一次想要按name
升序排序,然后按address
降序排序,另一次只按id
降序排序。
而且我不想创建自己的排序方法(即,我想使用Collections.sort(personList, someComparator)
。实现这一目标的最优雅的解决方案是什么?
发布于 2009-09-14 13:26:34
我认为您的枚举方法基本上是合理的,但是switch语句确实需要一种更面向对象的方法。考虑一下:
enum PersonComparator implements Comparator<Person> {
ID_SORT {
public int compare(Person o1, Person o2) {
return Integer.valueOf(o1.getId()).compareTo(o2.getId());
}},
NAME_SORT {
public int compare(Person o1, Person o2) {
return o1.getFullName().compareTo(o2.getFullName());
}};
public static Comparator<Person> decending(final Comparator<Person> other) {
return new Comparator<Person>() {
public int compare(Person o1, Person o2) {
return -1 * other.compare(o1, o2);
}
};
}
public static Comparator<Person> getComparator(final PersonComparator... multipleOptions) {
return new Comparator<Person>() {
public int compare(Person o1, Person o2) {
for (PersonComparator option : multipleOptions) {
int result = option.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
};
}
}
一个使用示例(使用静态导入)。
public static void main(String[] args) {
List<Person> list = null;
Collections.sort(list, decending(getComparator(NAME_SORT, ID_SORT)));
}
发布于 2009-09-14 13:09:54
您可以为您可能想要排序的每个属性创建比较器,然后尝试“比较器链”:-)如下所示:
public class ChainedComparator<T> implements Comparator<T> {
private List<Comparator<T>> simpleComparators;
public ChainedComparator(Comparator<T>... simpleComparators) {
this.simpleComparators = Arrays.asList(simpleComparators);
}
public int compare(T o1, T o2) {
for (Comparator<T> comparator : simpleComparators) {
int result = comparator.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
}
发布于 2009-09-14 12:43:29
一种方法是创建一个Comparator
,它将属性列表作为参数进行排序,如本例所示。
public class Person {
private int id;
private String name, address;
public static Comparator<Person> getComparator(SortParameter... sortParameters) {
return new PersonComparator(sortParameters);
}
public enum SortParameter {
ID_ASCENDING, ID_DESCENDING, NAME_ASCENDING,
NAME_DESCENDING, ADDRESS_ASCENDING, ADDRESS_DESCENDING
}
private static class PersonComparator implements Comparator<Person> {
private SortParameter[] parameters;
private PersonComparator(SortParameter[] parameters) {
this.parameters = parameters;
}
public int compare(Person o1, Person o2) {
int comparison;
for (SortParameter parameter : parameters) {
switch (parameter) {
case ID_ASCENDING:
comparison = o1.id - o2.id;
if (comparison != 0) return comparison;
break;
case ID_DESCENDING:
comparison = o2.id - o1.id;
if (comparison != 0) return comparison;
break;
case NAME_ASCENDING:
comparison = o1.name.compareTo(o2.name);
if (comparison != 0) return comparison;
break;
case NAME_DESCENDING:
comparison = o2.name.compareTo(o1.name);
if (comparison != 0) return comparison;
break;
case ADDRESS_ASCENDING:
comparison = o1.address.compareTo(o2.address);
if (comparison != 0) return comparison;
break;
case ADDRESS_DESCENDING:
comparison = o2.address.compareTo(o1.address);
if (comparison != 0) return comparison;
break;
}
}
return 0;
}
}
}
然后可以在代码中使用它,例如:
cp = Person.getComparator(Person.SortParameter.ADDRESS_ASCENDING,
Person.SortParameter.NAME_DESCENDING);
Collections.sort(personList, cp);
https://stackoverflow.com/questions/1421322
复制相似问题