一、List接口中sort方法
首先来看一下List接口中的sort()
方法
从这个描述我们可以看到,我们可以根据具体的Comparator对List结合中的元素进行排序,如果传入的comparator是null的时候,那么集合中的元素必须实现Comparable接口实现自然排序。从上面的一段话我们知道List集合对元素排序的方法有以下两种
方法 | 方法描述 |
---|---|
方法一 | List中的元素自己实现一个Comparable接口实现一个自然排序 |
方法二 | 我们通过传入一个实现了Comparator接口实现一个排序 |
顺便提一句:对于集合的排序算法,底层使用的是MergeSort
二、代码实现
2.1、List中的元素自己实现一个Comparable接口实现一个自然排序
这里我实现对Person 中age这个字段进行排序
package CollectionLearn; import org.junit.Test; import java.util.ArrayList; import java.util.Comparator; import java.util.List; /** * List排序 */ public class SortList { private List<Person> list = new ArrayList<Person>(); private Person p1 = new Person(2,"name1"); private Person p2 = new Person(3,"name3"); private Person p3 = new Person(1,"name4"); private Person p4 = new Person(4,"name2"); @Test public void testCommonType_I(){ list.add(p1); list.add(p2); list.add(p3); list.add(p4); list.sort(null); // 传入的Comparator=null,实现自然排序 // 遍历集合 list.forEach(item->{ System.out.println(item.toString()); }); } } class Person implements Comparable{ int age; String name; public Person(){}; public Person(int age,String name){ this.age = age; this.name = 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; } @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}'; } @Override public int compareTo(Object o) { Person p = (Person)o; if(this.getAge()-p.getAge()<0){ return -1; } if(this.getAge()-p.getAge()>0){ return 1; } return 0; } }
输出结果:
Person{age=1, name='name4'} Person{age=2, name='name1'} Person{age=3, name='name3'} Person{age=4, name='name2'}
如果Person对象没有实现Comparable接口,那么就会抛出下面的异常:
java.lang.ClassCastException: CollectionLearn.Person cannot be cast to java.lang.Comparable at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320) at java.util.ComparableTimSort.sort(ComparableTimSort.java:188) at java.util.Arrays.sort(Arrays.java:1312) at java.util.Arrays.sort(Arrays.java:1506) at java.util.ArrayList.sort(ArrayList.java:1460)
2.2、我们通过实现一个Comparator接口的类对Person对象进行排序
/** * 用户名 比较器 */ class PersonNameComparator implements Comparator<Person>{ @Override public int compare(Person o1, Person o2) { return o1.compareTo(o2); } }
测试代码:
@Test public void testCommonType_II() { list.add(p1); list.add(p2); list.add(p3); list.add(p4); list.sort(new PersonNameComparator()); // 遍历集合 list.forEach(item->{ System.out.println(item.toString()); }); }
注意:List排序可以直接采用Collections的sort()方法,也可以使用Arrays的sort()方法,归根结底Collections就是调用Arrays的sort()方法。
@Test public void testCommonType_II() { list.add(p1); list.add(p2); list.add(p3); list.add(p4); Collections.sort(list, new PersonNameComparator()); // 遍历集合 list.forEach(item->{ System.out.println(item.toString()); }); }
三、多维度(多字段)排序
有了上述基础后,实现多维度(多字段)排序就非常简单了,举例如下:
1、实体类
package CollectionLearn; /** * 学生 实体类 */ public class Student { /** * 学号 */ int id ; /** * 分数 */ int score; public Student(int id, int score) { this.id = id; this.score = score; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } }
2、实现Comparator接口
package CollectionLearn; import java.util.Comparator; /** * 通过实现Comparator接口对List集合进行多维度排序 * 举例:对学生的成绩进行排名,成绩相同的按照学号大小排序 */ public class SortUtilForList implements Comparator<Student> { /** * 为学生进行排名 * * @param o1 * @param o2 * @return */ @Override public int compare(Student o1, Student o2) { if (o1 instanceof Student){ if (o1.getScore() != o2.getScore()) { // 如果学生的分数不同,按照分数进行排名 return compareWithScore(o1.getScore(), o2.getScore()); } else { // 如果学生的分数相同按照学号进行排名 return compareWithId(o1.getId(), o2.getId()); } } return 0; } /** * 通过学生的学号进行排序(降序) * * @param id1 * @param id2 * @return */ private int compareWithId(int id1, int id2) { if (id1 > id2) { return -1; } return 1; } /** * 通过学生的分数进行排序(降序) * * @param score1 * @param score2 * @return */ private int compareWithScore(int score1, int score2) { if (score1 > score2) { return -1; } return 1; } }
3、测试
package CollectionLearn; import Student; import org.junit.Test; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static org.junit.Assert.*; public class SortUtilForListTest { @Test public void testCompare() throws Exception { SortUtilForList sortUtilForList = new SortUtilForList(); List<Student> students = new ArrayList<Student>(); students.add(new Student(1, 88)); students.add(new Student(3, 98)); students.add(new Student(4, 88)); students.add(new Student(2, 78)); students.add(new Student(6, 68)); students.add(new Student(5, 88)); Collections.sort(students, sortUtilForList); students.toString(); } }