java自定义排序

有一个类,存储学生信息,第一个成员是年龄,第二个是身高,有一个学生容器数组,按照自定义规则进行排序,首先按照年龄升序排序,年龄相同的,按照身高升序排序,下面是示例代码:

import java.util.Arrays;
import java.util.Comparator;

class Student {
    private int age;
    private double height;

    public Student(int age, double height) {
        this.age = age;
        this.height = height;
    }

    public int getAge() {
        return age;
    }

    public double getHeight() {
        return height;
    }
}

public class Students {
    public static void main(String[] args) {
        Student[] students = new Student[5];
        students[0] = new Student(20, 170.5);
        students[1] = new Student(18, 165.6);
        students[2] = new Student(20, 170.4);
        students[3] = new Student(19, 165.4);
        students[4] = new Student(18, 165.5);

        // 使用自定义规则对学生数组进行排序
        Arrays.sort(students, new Comparator() {
            @Override
            public int compare(Student s1, Student s2) {
                // 首先按照年龄升序排序
                int ageComparison = Integer.compare(s1.getAge(), s2.getAge());
                if (ageComparison != 0) {
                    return ageComparison;
                }

                // 年龄相同,按照身高升序排序
                return Double.compare(s1.getHeight(), s2.getHeight());
            }
        });

        // 打印排序后的学生信息
        for (Student student : students) {
            System.out.println("Age: " + student.getAge() + ", Height: " + student.getHeight());
        }
    }
}

输出:

Age: 18, Height: 165.5
Age: 18, Height: 165.6
Age: 19, Height: 165.4
Age: 20, Height: 170.4
Age: 20, Height: 170.5

注意其中在声明比较规则的匿名内部类时我们使用了

return Double.compare(s1.getHeight(), s2.getHeight());

而不是

return (int)(s1.getHeight()- s2.getHeight());

为什么呢,首先我们知道Array的sort函数在升序时的规则为,当左边的数大于右边的数应当返回正整数,反之返回负整数,如果相等则返回0。而当俩个浮点数的差不到1时,强转int得到的值为0,会导致错误排序,而java已经考虑了这点给我们提供了方便的比较函数。

可以打开库函数看看Double.compare的逻辑:

public static int compare(double d1, double d2) {
        if (d1 < d2)
            return -1;           // Neither val is NaN, thisVal is smaller
        if (d1 > d2)
            return 1;            // Neither val is NaN, thisVal is larger

        // Cannot use doubleToRawLongBits because of possibility of NaNs.
        long thisBits    = Double.doubleToLongBits(d1);
        long anotherBits = Double.doubleToLongBits(d2);

        return (thisBits == anotherBits ?  0 : // Values are equal
                (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
                 1));                          // (0.0, -0.0) or (NaN, !NaN)
}

你可能感兴趣的:(java,java,jvm,算法)