对对象集合进行排序[重复]

时间:2022-09-06 12:48:43

This question already has an answer here:

这个问题已经有了答案:

If I have a simple list of Strings:

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

List<String> stringList = new ArrayList<String>();

I can sort it with:

我可以用:

Collections.sort(stringList);

But suppose I have a Person class:

但假设我有一个人班:

public class Person
{
   private String name;
   private Integer age;
   private String country;
}

And a list of it:

它的列表如下:

List<Person> personList = new ArrayList<Person>();

And I want to sort it sometimes by name, sometimes by age, sometimes by country.

我想按名字,年龄,国家来分类。

What is the easiest way to accomplish that?

最简单的方法是什么?

I know that I can implement the Comparable interface, but that seems to limit me to sort it by one specific property.

我知道我可以实现可比的接口,但这似乎限制了我按一个特定属性对它进行排序。

9 个解决方案

#1


34  

Implement the Comparator interface (once for each different sort order) and use the Collections.sort() method that takes a Comparator as additional parameter.

实现比较器接口(对每个不同的排序顺序执行一次),并使用以比较器作为附加参数的Collections.sort()方法。

#2


48  

Collections.sort can be called with a custom comparator. And that comparator can be implemented to allow sorting in different sort orders. Here's an example (for your Person model - with age as an Integer):

集合。可以使用自定义比较器调用排序。可以实现比较器,以允许按不同的排序顺序排序。这里有一个例子(对于你的个人模型——以年龄为整数):

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;
  }
}

And you use it like that (assuming persons is a field):

你这样使用(假设人是场):

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
}

#3


15  

Thanks to the responders. For the benefit of others, I'd like to include a complete example.

由于反应者。为了其他人的利益,我想包括一个完整的例子。

The solution is the create the following additional classes:

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

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());
    }
}

The list can then be sorted like this:

列表可以这样排序:

Collections.sort(personList, new NameComparator());
Collections.sort(personList, new AgeComparator());
Collections.sort(personList, new CountryComparator());

#4


9  

The Java 8 way of doing this is to use List.sort as follows:

Java 8的方法是使用列表。排序如下:

personList.sort(Comparator.comparing(Person::getName));

To quote Stuart Marks in his answer over here.

引用Stuart Marks的回答。

This is the big advantage of the List.sort(cmp) extension method over Collections.sort(list, cmp). It might seem that this is merely a small syntactic advantage being able to write myList.sort(cmp) instead of Collections.sort(myList, cmp). The difference is that myList.sort(cmp), being an interface extension method, can be overridden by the specific List implementation. For example, ArrayList.sort(cmp) sorts the list in-place using Arrays.sort() whereas the default implementation implements the old copyout-sort-copyback technique.

这是List.sort(cmp)扩展方法优于集合的一大优点。(列表,cmp)。看起来这只是一个小小的语法优势,能够编写myList.sort(cmp)而不是集合。sort(myList cmp)。区别是myList.sort(cmp)作为接口扩展方法,可以被特定的列表实现覆盖。例如,ArrayList.sort(cmp)使用array .sort()对列表进行就地排序,而默认实现实现了旧的copyout-sort-copyback技术。

#5


5  

You could also use the BeanComparator from apache commons beanutils, like this:

您还可以使用apache commons beanutils中的BeanComparator,如下所示:

Collections.sort(personList, new BeanComparator("name"));

#6


3  

Implement 3 different types of Comparator.

实现3种不同类型的比较器。

you can add the comparator to the sort command. The comparator you define, will sort the elements by name, age, or what ever.

您可以将比较器添加到sort命令中。您所定义的比较器将按名称、年龄或其他什么对元素进行排序。

Collections.sort(list, new Comparator() {

        public int compare(Object arg0, Object arg1) {
            if (!(arg0 instanceof Person)) {
                return -1;
            }
            if (!(arg1 instanceof Person)) {
                return -1;
            }

            Person pers0 = (Person)arg0;
            Person pers1 = (Person)arg1;


            // COMPARE NOW WHAT YOU WANT
            // Thanks to Steve Kuo for your comment!
            return pers0.getAge() - pers1.getAge();
        }
    });

#7


2  

The Collections.sort method can be invoked with a second argument which is the comparator to use. Create 3 comparators and use the one you want when appropriate.

的集合。排序方法可以用第二个参数调用,该参数是要使用的比较器。创建3个比较器,并在适当的时候使用所需的比较器。

Collections.sort(list , new Comparator() {
        public int compare(Object o1, Object o2) {
          ...
        }
      });

#8


0  

I asked a very similar question (about searching rather than sorting), perhaps there is some useful information (I ended up using an enum that implements Comparator so I pass the enum value as a comparator selector).

我问了一个非常相似的问题(关于搜索而不是排序),也许有一些有用的信息(我最后使用实现比较器的enum,因此我将enum值作为比较器选择器传递)。

#9


0  

Using lambdaj ( http://code.google.com/p/lambdaj/ ) you can achieve what you're asking in the following way:

使用lambdaj (http://code.google.com/p/lambdaj/)您可以通过以下方式实现您的请求:

sort(personList, on(Person.class).getName());

排序(personList(Person.class). getname());

sort(personList, on(Person.class).getAge());

排序(personList(Person.class).getAge());

sort(personList, on(Person.class).getCountry());

排序(personList(Person.class).getCountry());

#1


34  

Implement the Comparator interface (once for each different sort order) and use the Collections.sort() method that takes a Comparator as additional parameter.

实现比较器接口(对每个不同的排序顺序执行一次),并使用以比较器作为附加参数的Collections.sort()方法。

#2


48  

Collections.sort can be called with a custom comparator. And that comparator can be implemented to allow sorting in different sort orders. Here's an example (for your Person model - with age as an Integer):

集合。可以使用自定义比较器调用排序。可以实现比较器,以允许按不同的排序顺序排序。这里有一个例子(对于你的个人模型——以年龄为整数):

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;
  }
}

And you use it like that (assuming persons is a field):

你这样使用(假设人是场):

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
}

#3


15  

Thanks to the responders. For the benefit of others, I'd like to include a complete example.

由于反应者。为了其他人的利益,我想包括一个完整的例子。

The solution is the create the following additional classes:

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

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());
    }
}

The list can then be sorted like this:

列表可以这样排序:

Collections.sort(personList, new NameComparator());
Collections.sort(personList, new AgeComparator());
Collections.sort(personList, new CountryComparator());

#4


9  

The Java 8 way of doing this is to use List.sort as follows:

Java 8的方法是使用列表。排序如下:

personList.sort(Comparator.comparing(Person::getName));

To quote Stuart Marks in his answer over here.

引用Stuart Marks的回答。

This is the big advantage of the List.sort(cmp) extension method over Collections.sort(list, cmp). It might seem that this is merely a small syntactic advantage being able to write myList.sort(cmp) instead of Collections.sort(myList, cmp). The difference is that myList.sort(cmp), being an interface extension method, can be overridden by the specific List implementation. For example, ArrayList.sort(cmp) sorts the list in-place using Arrays.sort() whereas the default implementation implements the old copyout-sort-copyback technique.

这是List.sort(cmp)扩展方法优于集合的一大优点。(列表,cmp)。看起来这只是一个小小的语法优势,能够编写myList.sort(cmp)而不是集合。sort(myList cmp)。区别是myList.sort(cmp)作为接口扩展方法,可以被特定的列表实现覆盖。例如,ArrayList.sort(cmp)使用array .sort()对列表进行就地排序,而默认实现实现了旧的copyout-sort-copyback技术。

#5


5  

You could also use the BeanComparator from apache commons beanutils, like this:

您还可以使用apache commons beanutils中的BeanComparator,如下所示:

Collections.sort(personList, new BeanComparator("name"));

#6


3  

Implement 3 different types of Comparator.

实现3种不同类型的比较器。

you can add the comparator to the sort command. The comparator you define, will sort the elements by name, age, or what ever.

您可以将比较器添加到sort命令中。您所定义的比较器将按名称、年龄或其他什么对元素进行排序。

Collections.sort(list, new Comparator() {

        public int compare(Object arg0, Object arg1) {
            if (!(arg0 instanceof Person)) {
                return -1;
            }
            if (!(arg1 instanceof Person)) {
                return -1;
            }

            Person pers0 = (Person)arg0;
            Person pers1 = (Person)arg1;


            // COMPARE NOW WHAT YOU WANT
            // Thanks to Steve Kuo for your comment!
            return pers0.getAge() - pers1.getAge();
        }
    });

#7


2  

The Collections.sort method can be invoked with a second argument which is the comparator to use. Create 3 comparators and use the one you want when appropriate.

的集合。排序方法可以用第二个参数调用,该参数是要使用的比较器。创建3个比较器,并在适当的时候使用所需的比较器。

Collections.sort(list , new Comparator() {
        public int compare(Object o1, Object o2) {
          ...
        }
      });

#8


0  

I asked a very similar question (about searching rather than sorting), perhaps there is some useful information (I ended up using an enum that implements Comparator so I pass the enum value as a comparator selector).

我问了一个非常相似的问题(关于搜索而不是排序),也许有一些有用的信息(我最后使用实现比较器的enum,因此我将enum值作为比较器选择器传递)。

#9


0  

Using lambdaj ( http://code.google.com/p/lambdaj/ ) you can achieve what you're asking in the following way:

使用lambdaj (http://code.google.com/p/lambdaj/)您可以通过以下方式实现您的请求:

sort(personList, on(Person.class).getName());

排序(personList(Person.class). getname());

sort(personList, on(Person.class).getAge());

排序(personList(Person.class).getAge());

sort(personList, on(Person.class).getCountry());

排序(personList(Person.class).getCountry());