我想使用比较器按降序对对象进行排序。
class Person {
private int age;
}
在这里,我想对一个Person对象数组进行排序。
我怎样才能做到这一点?
您可以用这种方法来覆盖用户定义的类的降序方法,从而覆盖compare()方法,
Collections.sort(unsortedList,new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return b.getName().compareTo(a.getName());
}
});
或通过使用Collection.reverse()用户Prince在其评论中提到的降序进行排序。
您可以像这样进行升序排序,
Collections.sort(unsortedList,new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
});
我们用简洁的Lambda表达式(从Java 8开始)替换上面的代码:
Collections.sort(personList, (Person a, Person b) -> b.getName().compareTo(a.getName()));
从Java 8开始,List具有sort()方法,该方法将Comparator作为参数(更简洁):
personList.sort((a,b)->b.getName().compareTo(a.getName()));
在这里a,b由lambda表达式推断为Person类型。
对于它的价值,这是我的标准答案。这里唯一的新内容是使用Collections.reverseOrder()。另外,它把所有建议都放在一个例子中:
/*
** Use the Collections API to sort a List for you.
**
** When your class has a "natural" sort order you can implement
** the Comparable interface.
**
** You can use an alternate sort order when you implement
** a Comparator for your class.
*/
import java.util.*;
public class Person implements Comparable<Person>
{
String name;
int age;
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name + " : " + age;
}
/*
** Implement the natural order for this class
*/
public int compareTo(Person p)
{
return getName().compareTo(p.getName());
}
static class AgeComparator implements Comparator<Person>
{
public int compare(Person p1, Person p2)
{
int age1 = p1.getAge();
int age2 = p2.getAge();
if (age1 == age2)
return 0;
else if (age1 > age2)
return 1;
else
return -1;
}
}
public static void main(String[] args)
{
List<Person> people = new ArrayList<Person>();
people.add( new Person("Homer", 38) );
people.add( new Person("Marge", 35) );
people.add( new Person("Bart", 15) );
people.add( new Person("Lisa", 13) );
// Sort by natural order
Collections.sort(people);
System.out.println("Sort by Natural order");
System.out.println("\t" + people);
// Sort by reverse natural order
Collections.sort(people, Collections.reverseOrder());
System.out.println("Sort by reverse natural order");
System.out.println("\t" + people);
// Use a Comparator to sort by age
Collections.sort(people, new Person.AgeComparator());
System.out.println("Sort using Age Comparator");
System.out.println("\t" + people);
// Use a Comparator to sort by descending age
Collections.sort(people,
Collections.reverseOrder(new Person.AgeComparator()));
System.out.println("Sort using Reverse Age Comparator");
System.out.println("\t" + people);
}
}
我将为人员类创建一个比较器,该比较器可以通过某种排序行为进行参数化。在这里,我可以设置排序顺序,但是可以对其进行修改以允许对其他人员属性进行排序。
public class PersonComparator implements Comparator<Person> {
public enum SortOrder {ASCENDING, DESCENDING}
private SortOrder sortOrder;
public PersonComparator(SortOrder sortOrder) {
this.sortOrder = sortOrder;
}
@Override
public int compare(Person person1, Person person2) {
Integer age1 = person1.getAge();
Integer age2 = person2.getAge();
int compare = Math.signum(age1.compareTo(age2));
if (sortOrder == ASCENDING) {
return compare;
} else {
return compare * (-1);
}
}
}
(希望它现在可以编译,我手边没有IDE或JDK,编码为“ blind”)
编辑
感谢Thomas,编辑了代码。我不会说Math.signum的用法很好,高效,有效,但是我想提醒一下,compareTo方法可以返回任何整数,并且如果()乘以(-1)将失败。实现返回Integer.MIN_INTEGER ...并且我删除了setter,因为它便宜得足以在需要时构造一个新的PersonComparator。
但是我保留拳击内容,因为它表明我依赖现有的Comparable实现。可以做类似的事情,Comparable<Integer> age1 = new Integer(person1.getAge());但是看起来太难看了。这个想法是要显示一种模式,该模式可以轻松地适应其他“人”属性,例如姓名,生日作为“日期”等等。
举报