Java中对集合进行排序的两种方法:
java集合的工具类Collections中提供了两种排序的方法,分别是:
- Collections.sort(List list)
- Collections.sort(List list,Comparator c)
1)第一种称为自然排序:
参与排序的对象需实现comparable接口(注:Interger和String不需要,java默认封装这个两个类实现了comparable接口),重写其compareTo()方法,方法体中实现对象的比较大小规则,示例如下:
package test; public class Emp implements Comparable { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Emp() { super(); } public Emp(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Emp [name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Emp emp) {
// return this.age-emp.getAge();//按照年龄升序排序 return this.name.compareTo(emp.getName());//换姓名升序排序
}
}
@Test //测试 public void testComparable(){ List list = new ArrayList(); list.add(new Emp(18, "tom")); list.add(new Emp(20,"jack")); list.add(new Emp(15,"rose")); list.add(new Emp(17,"jerry")); System.out.println("排序前:"); for(Emp o : list){ System.out.println(o); } Collections.sort(list); System.out.println("自然排序按age排序后:"); for(Emp o : list) { System.out.println(o); } }
输出结果:
分析:第一种方法不够灵活,要求实体类(集合元素)必须实现comparable接口,并且定义比较规则,这样导致会增加耦合,不利于程序的扩展;如果在项目中不同的位置需要根据不同的属性调用排序方法时,需要反复修改比较规则(按name还是按age),二者只能选择其一,会起冲突,所以不建议使用这个构造方法。第二种就很好地解决了这个问题,在需要的地方,创建个内部类的实例,重写其比较方法即可。
2)第二种叫自定义排序:
方法一:自定义一个Comparator比较器对象,然后传入Collections.sort(List,Comparator)排序方法中进行排序自定义的比较器:
bean(实体类--集合元素):
public class Emp{ private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Emp(int age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "Emp{" + "age=" + age + ", name='" + name + '\'' + '}'; } }
测试代码如下:
import java.util.Comparator; public class MyComparator implements Comparator<Emp>{ @Override public int compare(Emp o1, Emp o2) { return o1.getAge()-o2.getAge();//根据传入的Emp的年龄age由小到大进行升序排序 } } 测试类: @Test public void testComparatorSortAge(){ List list = new ArrayList(); list.add(new Emp(18, "tom")); list.add(new Emp(20,"jack")); list.add(new Emp(15,"rose")); list.add(new Emp(17,"jerry")); System.out.println("排序前:"); for(Emp o : list){ System.out.println(o); } Collections.sort(list,MyComparator);
System.out.println("使用Comparator比较器自定义按age升序排序后:");
for(Emp o : list){
System.out.println(o);
}
}
输出结果:
方法二:采用匿名内部的形式(推荐做法):
先new一个Comparator接口的比较器对象,同时实现compare()其方法;然后将比较器对象传给Collections.sort()方法的参数列表中,实现排序功能。
@Test public void testComparatorSortName(){ List list = new ArrayList(); list.add(new Emp(18, "tom")); list.add(new Emp(20,"jack")); list.add(new Emp(15,"rose")); list.add(new Emp(17,"jerry")); System.out.println("排序前:"); for(Emp o : list){ System.out.println(o); } Collections.sort(list, new Comparator() { @Override public int compare(Emp o1, Emp o2) { return o1.getName.compareTo(o2.getName); } }); System.out.println("使用Comparator比较器自定义按name升序排序后:"); for(Emp o : list){ System.out.println(o); } }
输出结果:
注:默认根据英文首字母大小比较排序,若首字母相同,则比较第二位字母大小,以此类推。
比较总结:
1.对于集合比较使用Collections.sort();
2.对于集合中的对象比较,需要指定比较逻辑,指定比较逻辑需要实现 Comparable接口并重写compareTo方法自定义逻辑。
3.对于需要临时改变比较规则,例如项目中存在多个场景调用不同的排序规则的情况时,需要使用Collections.sort(List,Comparator),采用回调方式重写Comparator接口的compare方法自定义逻辑。
参考文章:
1.https://blog.csdn.net/qq_43437465/article/details/89437637