[Java] Sort Java objects

Posted by csimms on Wed, 18 Sep 2019 06:08:38 +0200

How to sort Java objects

object order

Direct comparison leads to 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("Zhang three 1", 13);
        Student s2 = new Student("Zhang three 2", 12);
        Student s3 = new Student("Zhang three 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;
}

If this is the case, it will directly lead to the following situation.

Looking at the exception information, you can see that Student cannot be converted to Comparable, which indicates that our Student class needs to implement Comparable interface. So let's try to implement Comparable interface.

Using Comparable Interface

I sort it here by age, so when implementing the compareTo method, I compare values by age field.

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("Zhang three 1", 13);
        Student s2 = new Student("Zhang three 2", 12);
        Student s3 = new Student("Zhang three 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("Before sorting:"+students);
        Collections.sort(students);
        System.out.println("After sorting:"+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("Before sorting:"+Arrays.toString(students));
        Arrays.sort(students);
        System.out.println("After sorting:"+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;
    }
}

Operation results:

So we can see that this sort of ordering happens according to our expected results.

Notes for Objects Stored in List

For objects stored in List, such as:

List<Student> students = new ArrayList<Student>();

Collections.sort(students);

There is an error in such code. The parameters received by the Collections.sort() method must implement the Comparable interface or use the form Collections. sort (students, new Comparable < Student >(){...} of anonymous internal classes).

Using anonymous inner classes

At the same time, we have another way to sort objects that do not implement the Comparable interface, which is to use anonymous inner classes.
By looking at the Arrays.sort() and Collections.sort() methods, we can see the following:

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)

So we've found that both the sort methods provided by java can be implemented using anonymous inner classes, so let's test them in this way.

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("Zhang three 1", 13);
        Student2 s2 = new Student2("Zhang three 2", 12);
        Student2 s3 = new Student2("Zhang three 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("Before sorting:"+students);
        Collections.sort(students, new Comparator<Student2>() {
            @Override
            public int compare(Student2 o1, Student2 o2) {

                return o1.getAge() - o2.getAge();
            }
        });
        System.out.println("After sorting:"+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("Before sorting:"+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("After sorting:"+Arrays.toString(students));
    }
}


@Data
@AllArgsConstructor
class Student2 {
    private String name;
    private int age;
}

Operation results:

We can see that the results of these two approaches are the same. So in both ways, the choice of QvQ depends entirely on personal will.

Topics: Java Lombok