如何对Java对象进行排序
ClassCastException
import lombok.AllArgsConstructor; import lombok.Data; import java.util.*; /** * @author niushuai * @date 2019/9/18 10:17 */ public class CompareDemo { public static void main(String[] args) { Student s1 = new Student("张三1", 13); Student s2 = new Student("张三2", 12); Student s3 = new Student("张三3", 11); arraysDemo(s1, s2, s3); } public static void arraysDemo(Student s1, Student s2, Student s3) { Student[] students = new Student[3]; students[0] = s1; students[1] = s2; students[2] = s3; Arrays.sort(students); System.out.println(Arrays.toString(students)); } } @Data @AllArgsConstructor class Student { private String name; private int age; }
假如这样的话会直接导致下图情况的出现。
看异常信息可以看到Student不能被转换为Comparable,标志着我们的Student类需要实现Comparable接口。那么我们就来试试实现Comparable接口的情况
我在这里按照年龄大小来排序,因此实现compareTo方法时按照 age
字段来比较值
import lombok.AllArgsConstructor; import lombok.Data; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * @author niushuai * @date 2019/9/18 10:17 */ public class CompareDemo { public static void main(String[] args) { Student s1 = new Student("张三1", 13); Student s2 = new Student("张三2", 12); Student s3 = new Student("张三3", 11); arraysDemo(s1, s2, s3); System.out.println("--------------------------------------------------------------------------------------------"); listDemo(s1, s2, s3); } public static void listDemo(Student s1, Student s2, Student s3) { List<Student> students = new ArrayList<Student>(); students.add(s1); students.add(s2); students.add(s3); System.out.println("排序前:"+students); Collections.sort(students); System.out.println("排序后:"+students); } public static void arraysDemo(Student s1, Student s2, Student s3) { Student[] students = new Student[3]; students[0] = s1; students[1] = s2; students[2] = s3; System.out.println("排序前:"+Arrays.toString(students)); Arrays.sort(students); System.out.println("排序后:"+Arrays.toString(students)); } } @Data @AllArgsConstructor class Student implements Comparable<Student> { private String name; private int age; @Override public int compareTo(Student o) { int result = 0; int targetAge = o.getAge(); int thisAge = this.getAge(); if (thisAge > targetAge) { result = 1; } else if (thisAge < targetAge) { result = -1; } return result; } }
运行结果:
因此我们可以看到 这样排序一切按照我们预期的结果出现了。
针对List中存储的对象如:
List<Student> students = new ArrayList<Student>(); Collections.sort(students);
这样的代码存在着一个错误, Collections.sort()
方法接收的参数必须要实现 Comparable
接口或者使用匿名内部类的形式 Collections.sort(students, new Comparable<Student>(){...});
同时我们还有另外一种方法来对未实现Comparable接口的对象来排序,那就是使用匿名内部类的方式。
通过查看Arrays.sort()和Collections.sort()方法时,我们会发现如下情况:
Arrays.sort(Object[] a) Arrays.sort(T[] a, Comparator<? super T> c) Collections.sort(List<T> list) Collections.sort(List<T> list, Comparator<? super T> c)
所以我们已经发现了,这两个java提供的排序方法都可以使用匿名内部类的方式来实现该方式,那么我们下面来使用这种方式进行测试。
import lombok.AllArgsConstructor; import lombok.Data; import java.util.*; /** * @author niushuai * @date 2019/9/18 10:25 */ public class CompareDemo2 { public static void main(String[] args) { Student2 s1 = new Student2("张三1", 13); Student2 s2 = new Student2("张三2", 12); Student2 s3 = new Student2("张三3", 11); arraysDemo(s1, s2, s3); System.out.println("--------------------------------------------------------------------------------------------"); listDemo(s1, s2, s3); } public static void listDemo(Student2 s1, Student2 s2, Student2 s3) { List<Student2> students = new ArrayList<Student2>(); students.add(s1); students.add(s2); students.add(s3); System.out.println("排序前:"+students); Collections.sort(students, new Comparator<Student2>() { @Override public int compare(Student2 o1, Student2 o2) { return o1.getAge() - o2.getAge(); } }); System.out.println("排序后:"+students); } public static void arraysDemo(Student2 s1, Student2 s2, Student2 s3) { Student2[] students = new Student2[3]; students[0] = s1; students[1] = s2; students[2] = s3; System.out.println("排序前:"+Arrays.toString(students)); Arrays.sort(students, new Comparator<Student2>() { @Override public int compare(Student2 o1, Student2 o2) { return o1.getAge() - o2.getAge(); } }); System.out.println("排序后:"+Arrays.toString(students)); } } @Data @AllArgsConstructor class Student2 { private String name; private int age; }
运行结果:
我们可以看到 这两种方式的结果一样。因此 两种方式,选用哪种就全凭个人意愿咯QvQ