java集合进行排序的两种方式
java集合的工具类Collections中提供了两种排序的方法,分别是:
- Collections.sort(List list)
- Collections.sort(List list,Comparator c)
第一种称为自然排序,参与排序的对象需实现comparable接口,重写其compareTo()方法,方法体中实现对象的比较大小规则,示例如下:
实体类:(基本属性,getter/setter方法,有参无参构造方法,toString方法)
1 package test; 2 3 public class Emp implements Comparable { 4 5 private String name; 6 private int age; 7 public String getName() { 8 return name; 9 } 10 public void setName(String name) { 11 this.name = name; 12 } 13 public int getAge() { 14 return age; 15 } 16 public void setAge(int age) { 17 this.age = age; 18 } 19 public Emp() { 20 super(); 21 } 22 public Emp(String name, int age) { 23 super(); 24 this.name = name; 25 this.age = age; 26 } 27 @Override 28 public String toString() { 29 return "Emp [name=" + name + ", age=" + age + "]"; 30 } 31 @Override 32 public int compareTo(Object o) { 33 if(o instanceof Emp){ 34 Emp emp = (Emp) o; 35 // return this.age-emp.getAge();//按照年龄升序排序 36 return this.name.compareTo(emp.getName());//换姓名升序排序 37 } 38 throw new ClassCastException("不能转换为Emp类型的对象..."); 39 } 40 41 }
第二种叫定制排序,或自定义排序,需编写匿名内部类,先new一个Comparator接口的比较器对象c,同时实现compare()其方法;
然后将比较器对象c传给Collections.sort()方法的参数列表中,实现排序功能;
说明:第一种方法不够灵活,实体类实现了comparable接口后,会增加耦合,如果在项目中不同的位置需要根据不同的属性调用排序方法时,需要反复修改比较规则(按name还是按age),二者只能选择其一,会起冲突.第二种就很好地解决了这个问题.在需要的地方,创建个内部类的实例,重写其比较方法即可.
jUnit4单元测试类代码如下:
1 package test; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 import java.util.List; 7 8 import org.junit.BeforeClass; 9 import org.junit.Test; 10 11 public class TestSort { 12 13 static List list = new ArrayList(); 14 //@BeforeClass注解标注的方法会在其它测试方法执行之前先执行, 15 //且只执行一次.@Before注解标注的方法会在每个测试方法之前执行; 16 //此处初始化集合只需要一次,因此使用@BeforeClass. 17 @BeforeClass 18 public static void init(){ 19 list.add(new Emp("tom",18)); 20 list.add(new Emp("jack",20)); 21 list.add(new Emp("rose",15)); 22 list.add(new Emp("jerry",17)); 23 System.out.println("排序前:"); 24 for(Object o : list){ 25 System.out.println(o); 26 } 27 } 28 29 /**按age升序排序*/ 30 // @Test 31 // public void testSortAge(){ 32 // Collections.sort(list); 33 // System.out.println("自然排序按age排序后:"); 34 // for(Object o : list){ 35 // System.out.println(o); 36 // } 37 // } 38 // 39 /**按name升序排序*/ 40 @Test 41 public void testSortName(){ 42 Collections.sort(list); 43 System.out.println("自然排序按name升序排序后:"); 44 for(Object o : list){ 45 System.out.println(o); 46 } 47 } 48 49 /**使用Comparator比较器按age升序排序*/ 50 @Test 51 public void testComparatorSortAge(){ 52 Collections.sort(list,new Comparator () { 53 @Override 54 public int compare(Object o1, Object o2) { 55 if(o1 instanceof Emp && o2 instanceof Emp){ 56 Emp e1 = (Emp) o1; 57 Emp e2 = (Emp) o2; 58 return e1.getAge() - e2.getAge(); 59 } 60 throw new ClassCastException("不能转换为Emp类型"); 61 } 62 }); 63 System.out.println("使用Comparator比较器按age升序排序后:"); 64 for(Object o : list){ 65 System.out.println(o); 66 } 67 } 68 /**使用Comparator比较器按name升序排序*/ 69 @Test 70 public void testComparatorSortName(){ 71 Collections.sort(list,new Comparator () { 72 @Override 73 public int compare(Object o1, Object o2) { 74 if(o1 instanceof Emp && o2 instanceof Emp){ 75 Emp e1 = (Emp) o1; 76 Emp e2 = (Emp) o2; 77 return e1.getName().compareTo(e2.getName()); 78 } 79 throw new ClassCastException("不能转换为Emp类型"); 80 } 81 }); 82 System.out.println("使用Comparator比较器按name升序排序后:"); 83 for(Object o : list){ 84 System.out.println(o); 85 } 86 } 87 88 }
右键空白位置 —> Run As —> JUnit Test —>
运行结果如下:
排序前: Emp [name=tom, age=18] Emp [name=jack, age=20] Emp [name=rose, age=15] Emp [name=jerry, age=17] 自然排序按name升序排序后: Emp [name=jack, age=20] Emp [name=jerry, age=17] Emp [name=rose, age=15] Emp [name=tom, age=18] 使用Comparator比较器按age升序排序后: Emp [name=rose, age=15] Emp [name=jerry, age=17] Emp [name=tom, age=18] Emp [name=jack, age=20] 使用Comparator比较器按name升序排序后: Emp [name=jack, age=20] Emp [name=jerry, age=17] Emp [name=rose, age=15] Emp [name=tom, age=18]