乐趣区

Java对Java对象进行排序

如何对 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 接口的情况

使用 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 中存储的对象如:

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

退出移动版