一、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();
}
}