Java 对对象集合进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1206073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sorting a collection of objects
提问by Knut Arne Vedaa
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:
但假设我有一个 Person 类:
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.
我知道我可以实现 Comparable 接口,但这似乎限制了我按一个特定属性对其进行排序。
采纳答案by Michael Borgwardt
Implement the Comparatorinterface (once for each different sort order) and use the Collections.sort()method that takes a Comparator as additional parameter.
实现Comparator接口(对于每个不同的排序顺序一次)并使用将Comparator 作为附加参数的Collections.sort()方法。
回答by Markus Lausberg
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.
您可以将比较器添加到排序命令中。您定义的比较器将按名称、年龄或其他任何内容对元素进行排序。
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();
}
});
回答by z5h
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.
可以使用第二个参数调用 Collections.sort 方法,该参数是要使用的比较器。创建 3 个比较器并在适当的时候使用你想要的一个。
Collections.sort(list , new Comparator() {
public int compare(Object o1, Object o2) {
...
}
});
回答by Andreas Dolk
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):
可以使用自定义比较器调用 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;
}
}
And you use it like that (assuming persons is a field):
您可以这样使用它(假设 people 是一个字段):
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
}
回答by Knut Arne Vedaa
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());
回答by J?rn Horstmann
You could also use the BeanComparatorfrom apache commons beanutils, like this:
你也可以使用BeanComparator从阿帕奇百科全书BeanUtils的,就像这样:
Collections.sort(personList, new BeanComparator("name"));
回答by Jason S
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
实现,Comparator
所以我将enum
值作为比较器选择器传递)。
回答by Mario Fusco
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());
sort(personList, on(Person.class).getName());
sort(personList, on(Person.class).getAge());
sort(personList, on(Person.class).getAge());
sort(personList, on(Person.class).getCountry());
sort(personList, on(Person.class).getCountry());
回答by aioobe
The Java 8 way of doing this is to use List.sort
as follows:
Java 8 这样做的方法是使用List.sort
如下:
personList.sort(Comparator.comparing(Person::getName));
To quote Stuart Marksin his answer over here.
在这里引用Stuart Marks的回答。
This is the big advantage of the
List.sort(cmp)
extension method overCollections.sort(list, cmp)
. It might seem that this is merely a small syntactic advantage being able to writemyList.sort(cmp)
instead ofCollections.sort(myList, cmp)
. The difference is thatmyList.sort(cmp)
, being an interface extension method, can be overriddenby the specificList
implementation. For example,ArrayList.sort(cmp)
sorts the list in-place usingArrays.sort()
whereas the default implementation implements the old copyout-sort-copyback technique.
这是
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 技术。