Java 对对象集合进行排序
如果我有一个简单的字符串列表:Java 对对象集合进行排序,java,sorting,collections,Java,Sorting,Collections,如果我有一个简单的字符串列表: List<String> stringList = new ArrayList<String>(); 但是假设我有一个Person类: public class Person { private String name; private Integer age; private String country; } 和一份清单: List<Person> personList = new ArrayList&
List<String> stringList = new ArrayList<String>();
但是假设我有一个Person类:
public class Person
{
private String name;
private Integer age;
private String country;
}
和一份清单:
List<Person> personList = new ArrayList<Person>();
List personList=new ArrayList();
我想有时按名字,有时按年龄,有时按国家来分类
最简单的方法是什么
我知道我可以实现Comparable接口,但这似乎限制了我按一个特定属性对其进行排序。实现3种不同类型的比较器 您可以将比较器添加到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();
}
});
实现接口(每个不同的排序顺序一次),并使用将比较器作为附加参数的方法。Collections.sort方法可以使用第二个参数调用,该参数是要使用的比较器。 创建3个比较器,并在适当时使用所需的比较器
Collections.sort(list , new Comparator() {
public int compare(Object o1, Object o2) {
...
}
});
可以使用自定义比较器调用Collections.sort。该比较器可以实现为允许以不同的排序顺序进行排序。以下是一个示例(适用于您的个人模型-年龄为整数):
公共类FlexiblePersonComparator实现Comparator{
公共枚举顺序{名称、年龄、国家}
私人订单排序方式=名称;
@凌驾
公共整数比较(个人1,个人2){
开关(分拣方式){
案例名称:返回person1.Name.compareTo(person2.Name);
病例年龄:返回人1.Age.compareTo(人2.Age);
案例国家:返回人1.Country.compareTo(返回人2.Country);
}
抛出新的RuntimeException(“实际上无法访问的代码,无法抛出”);
}
公共无效设置排序依据(排序依据){
this.sortingBy=sortingBy;
}
}
您可以这样使用它(假设persons是一个字段):
public void排序依据(flexiblePersonCompactor.Order排序依据){
List persons=this.persons;//无用行,仅供澄清
FlexiblePersonComparator比较器=新的FlexiblePersonComparator();
比较器。设置排序依据(排序依据);
Collections.sort(persons,comparator);//现在我们有了一个排序列表
}
感谢响应者。为了其他人的利益,我想包括一个完整的例子
解决方案是创建以下附加类:
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());
}
}
您还可以使用来自apache commons beanutils的,如下所示:
Collections.sort(personList, new NameComparator());
Collections.sort(personList, new AgeComparator());
Collections.sort(personList, new CountryComparator());
Collections.sort(personList, new BeanComparator("name"));
我问了a(关于搜索而不是排序),也许有一些有用的信息(我最终使用了实现比较器的enum
,因此我将enum
值作为比较器选择器传递)。使用lambdaj()可以通过以下方式实现您的要求:
排序(personList,on(Person.class).getName())
排序(personList,on(Person.class.getAge())
排序(personList,on(Person.class).getCountry()) Java 8实现这一点的方法如下所示:
personList.sort(Comparator.comparing(Person::getName));
在他的回答中引用
这是List.sort(cmp)
扩展方法相对于Collections.sort(List,cmp)
的最大优势。这似乎只是一个很小的语法优势,可以编写myList.sort(cmp)
而不是Collections.sort(myList,cmp)
。区别在于,myList.sort(cmp)
,作为一种接口扩展方法,可以被特定的列表
实现覆盖。例如,ArrayList.sort(cmp)
使用Arrays.sort()
对列表进行就地排序,而默认实现实现实现了旧的copyout-sort-copyback技术
啊。。。比较器。。。合成糖很好吃!是的,我也这么认为。它应该是Collections.sort(Person,new Comparator(){
为什么不为Comparator使用参数化类型?因为我来自1.4;),您可以只返回pers0.getAge()-pers1.getAge()。这将适用于三种情况(and==).+1我喜欢灵活的Comparatory的想法。您还可以在构造函数中传递sortingBy参数。演示了enum在使用comparator链接进行自定义排序和分组排序(多个参数)时的优雅用法。这应该是可以接受的答案也许您不应该使用形容词“composite”在标题中,因为它听起来像复合模式…很好的一个。以前从未见过
Collections.sort(personList, new NameComparator());
Collections.sort(personList, new AgeComparator());
Collections.sort(personList, new CountryComparator());
Collections.sort(personList, new BeanComparator("name"));
personList.sort(Comparator.comparing(Person::getName));