自定义对象比较器,结果失真怎么办?

奋斗的软件工程师 / 2024-01-27 / 原文

如果自定义对象比较器的结果失真,那么首先需要确认比较器的compare方法是否正确实现。在Java中,compare方法应该返回一个负整数、零或正整数,分别表示第一个参数小于、等于或大于第二个参数。

例如,如果我们正在比较两个Student对象,我们可能会根据他们的身高或年龄来排序。但是,如果我们的compare方法返回的是两个年龄的差值,那么当两个学生的年龄相差很大时(身高浮点数作差),结果可能会出现失真。这是因为Java的整数类型可能会溢出。

为了避免这种情况,我们可以使用Integer.compare方法来比较两个整数(Double.compare),而不是直接相减。这样可以避免溢出的问题,并且可以正确处理负数的情况。

点击查看代码
package com.itheima.javase;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Comparator;

public class Demo {
    public static void main(String[] args) {
        // 示例1:使用Arrays.sort对基本数据类型数组进行排序
        fun1();

        System.out.println();

        // 示例2:实现Comparable接口对自定义类(User)进行排序
        fun2();

        System.out.println();

        // 示例3:使用Comparator接口对自定义类(Student)进行排序
        fun3();
    }

    // 示例1:使用Arrays.sort对基本数据类型数组进行排序
    private static void fun1() {
        int[] arr1 = new int[]{9, 2, 8, 1, 5, 1};

        // 默认是升序
        Arrays.sort(arr1);

        System.out.println(Arrays.toString(arr1));
    }

    // 示例2:实现Comparable接口对自定义类(User)进行排序
    private static void fun2() {
        User[] users = new User[]{
                new User("张三", 172.8, 23),
                new User("李四", 156.8, 28),
                new User("王五", 192.2, 22),
                new User("赵六", 184.8, 25),
        };

        // 使用Arrays.sort默认的Comparable排序(按年龄降序)
        Arrays.sort(users);

        for (User user : users) {
            System.out.println(user);
        }
    }

    // 示例3:使用Comparator接口对自定义类(Student)进行排序
    private static void fun3() {
        Student[] students = new Student[]{
                new Student("张三", 172.8, 23),
                new Student("李四", 156.8, 28),
                new Student("王五", 192.2, 22),
                new Student("赵六", 184.8, 25),
        };

        // 使用Comparator接口进行排序(按身高升序)
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 使用Double.compare比较浮点数
                return Double.compare(o1.getHeight(), o2.getHeight());
            }
        });

        for (Student student : students) {
            System.out.println(student);
        }
    }
}

class Student {
    private String name;
    private double height;
    private int age;

    public Student() {
    }

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

    // Getter and Setter methods

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", age=" + age +
                '}';
    }
}

class User implements Comparable<User> {
    private String name;
    private double height;
    private int age;

    public User() {
    }

    public User(String name, double height, int age) {
        this.name = name;
        this.height = height;
        this.age = age;
    }

    // Getter and Setter methods

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", age=" + age +
                '}';
    }

    // 实现Comparable接口的compareTo方法,按年龄降序排序
    @Override
    public int compareTo(User o) {
        return o.age - this.age;
    }
}