对对象集合进行排序

Knu*_*daa 60 java sorting collections

如果我有一个简单的字符串列表:

List<String> stringList = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)

我可以用它来分类:

Collections.sort(stringList);
Run Code Online (Sandbox Code Playgroud)

但是假设我有一个Person类:

public class Person
{
   private String name;
   private Integer age;
   private String country;
}
Run Code Online (Sandbox Code Playgroud)

并列出一个:

List<Person> personList = new ArrayList<Person>();
Run Code Online (Sandbox Code Playgroud)

我希望有时按名字排序,有时按年龄,有时按国家排序.

最简单的方法是什么?

我知道我可以实现Comparable接口,但这似乎限制我按一个特定属性对其进行排序.

And*_*s_D 48

可以使用自定义比较器调用Collections.sort.并且可以实现该比较器以允许以不同的排序顺序进行排序.这是一个例子(对于你的Person模型 - 年龄为整数):

public class FlexiblePersonComparator implements Comparator<Person> {
  public enum Order {Name, Age, Country}

  private Order sortingBy = Name;

  @Override
  public int compare(Person person1, Person person2) {
    switch(sortingBy) {
      case Name: return person1.name.compareTo(person2.name);
      case Age: return person1.age.compareTo(person2.age);
      case Country: return person1.country.compareTo(person2.country);
    }
    throw new RuntimeException("Practically unreachable code, can't be thrown");
  }

  public void setSortingBy(Order sortBy) {
    this.sortingBy = sortingBy;
  }
}
Run Code Online (Sandbox Code Playgroud)

你就这样使用它(假设人是一个领域):

public void sortPersonsBy(FlexiblePersonComparator.Order sortingBy) {
  List<Person> persons = this.persons;  // useless line, just for clarification
  FlexiblePersonComparator comparator = new FlexiblePersonComparator();
  comparator.setSortingBy(sortingBy);
  Collections.sort(persons, comparator); // now we have a sorted list
}
Run Code Online (Sandbox Code Playgroud)

  • 您还可以在构造函数中传递sortingBy参数. (4认同)
  • +1我喜欢灵活的比较器的想法 (2认同)

Mic*_*rdt 35

实现Comparator接口(每个不同的排序顺序一次)并使用Collections.sort()方法,该方法将Comparator作为附加参数.


Knu*_*daa 17

感谢响应者.为了他人的利益,我想提供一个完整的例子.

解决方案是创建以下附加类:

public class NameComparator implements Comparator<Person>
{
    public int compare(Person o1, Person o2)
    {
       return o1.getName().compareTo(o2.getName());
   }
}

public class AgeComparator implements Comparator<Person>
{
    public int compare(Person o1, Person o2)
    {
        return o1.getAge().compareTo(o2.getAge());
    }
}

public class CountryComparator implements Comparator<Person>
{
    public int compare(Person o1, Person o2)
    {
        return o1.getCountry().compareTo(o2.getCountry());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后可以按如下方式对列表进行排序:

Collections.sort(personList, new NameComparator());
Collections.sort(personList, new AgeComparator());
Collections.sort(personList, new CountryComparator());
Run Code Online (Sandbox Code Playgroud)


aio*_*obe 10

Java 8的方法是使用List.sort如下:

personList.sort(Comparator.comparing(Person::getName));
Run Code Online (Sandbox Code Playgroud)

引用Stuart Marks这里的回答.

这是List.sort(cmp)扩展方法的一大优势Collections.sort(list, cmp).看起来这似乎只是一个小的语法优势,能够写myList.sort(cmp)而不是Collections.sort(myList, cmp).不同之处在于myList.sort(cmp),作为接口扩展方法,可以被特定List实现覆盖.例如,使用ArrayList.sort(cmp)原样对列表进行排序,Arrays.sort()而默认实现实现旧的copyout-sort-copyback技术.


Jör*_*ann 6

你也可以使用BeanComparator从阿帕奇百科全书BeanUtils的,就像这样:

Collections.sort(personList, new BeanComparator("name"));
Run Code Online (Sandbox Code Playgroud)