使用比较器 - 降序排序(用户定义的类)

Man*_*noj 66 java

我想使用比较器按降序对对象进行排序.

class Person {
 private int age;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我想对Person对象的数组进行排序.

我怎样才能做到这一点?

Luc*_*cky 103

您可以通过这种方式执行降序的用户定义类来覆盖compare()方法,

Collections.sort(unsortedList,new Comparator<Person>() {
    @Override
    public int compare(Person a, Person b) {
        return b.getName().compareTo(a.getName());
    }
});
Run Code Online (Sandbox Code Playgroud)

或者通过使用Prince他的评论中提到的Collection.reverse()降序排序.

你可以这样做升序排序,

Collections.sort(unsortedList,new Comparator<Person>() {
    @Override
    public int compare(Person a, Person b) {
        return a.getName().compareTo(b.getName());
    }
});
Run Code Online (Sandbox Code Playgroud)

用Lambda表达式替换上面的代码(Java 8以后)我们简明扼要:

Collections.sort(personList, (Person a, Person b) -> b.getName().compareTo(a.getName()));
Run Code Online (Sandbox Code Playgroud)

从Java 8开始,List有sort()方法,它以Comparator为参数(更简洁):

personList.sort((a,b)->b.getName().compareTo(a.getName()));
Run Code Online (Sandbox Code Playgroud)

这里ab通过lambda表达式推断为Person类型.

  • 或者你可以使用`Collections.reverseOrder(...)`进行降序排序. (22认同)

cam*_*ckr 63

对于什么,它的价值在于我的标准答案.这里唯一新的是使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)


And*_*s_D 16

我会为person类创建一个比较器,可以使用某种排序行为进行参数化.在这里,我可以设置排序顺序,但也可以修改它以允许对其他人属性进行排序.

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);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

(希望它现在编译,我手头没有IDE或JDK,编码'盲目')

编辑

感谢Thomas,编辑了代码.我不会说Math.signum的用法是好的,高性能的,有效的,但是我想保留它作为提示,compareTo方法可以返回任何整数,乘以(-1)将失败,如果实现返回Integer.MIN_INTEGER ...我删除了setter,因为它足够便宜,可以在需要时构建一个新的PersonComparator.

但我保持拳击,因为它表明我依赖现有的可比较实现.可能做过类似Comparable<Integer> age1 = new Integer(person1.getAge());但看起来太丑陋的事情.我们的想法是展示一个可以轻松适应其他Person属性的模式,比如名称,生日作为Date等等.

  • 曾几何时,有一个好习惯是发表评论,以帮助刚刚投票的作者改进他的信息. (6认同)

Tho*_*ung 14

String[] s = {"a", "x", "y"};
Arrays.sort(s, new Comparator<String>() {

    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});
System.out.println(Arrays.toString(s));

-> [y, x, a]
Run Code Online (Sandbox Code Playgroud)

现在,您必须为Person类实现Comparator.像(升序)的东西:compare(Person a, Person b) = a.id < b.id ? -1 : (a.id == b.id) ? 0 : 1Integer.valueOf(a.id).compareTo(Integer.valueOf(b.id)).

为了最大限度地减少混淆,你应该实现一个升序比较器,然后使用包装器将其转换为降序比较器(如下所示)new ReverseComparator<Person>(new PersonComparator()).


fin*_*nnw 5

使用Google Collections:

class Person {
 private int age;

 public static Function<Person, Integer> GET_AGE =
  new Function<Person, Integer> {
   public Integer apply(Person p) { return p.age; }
  };

}

public static void main(String[] args) {
 ArrayList<Person> people;
 // Populate the list...

 Collections.sort(people, Ordering.natural().onResultOf(Person.GET_AGE).reverse());
}
Run Code Online (Sandbox Code Playgroud)

  • 超越风格:) (2认同)