• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

奋斗的软件工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

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

如果自定义对象比较器的结果失真,那么首先需要确认比较器的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());
            }

        
        
        });

          //或者使用BigDecimal的方式可以确保精确表示身高

            Arrays.sort(peoples, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                BigDecimal height1 = BigDecimal.valueOf(o1.getHeight());
                BigDecimal height2 = BigDecimal.valueOf(o2.getHeight());
                return height1.compareTo(height2);
            }
        });

使用BigDecimal的方式可以确保精确表示身高,因为BigDecimal类提供了对十进制浮点数的精确表示和运算支持。这种方法适用于需要确保精确性的情况,特别是在金融领域或者需要对浮点数进行精确计算时。

而使用Double.compare方法进行比较也是一种常见的做法,它是针对基本数据类型double的比较操作,通常用于一般性的比较场景。虽然在极端情况下可能会出现精度丢失的问题,但在大多数情况下,这种精度丢失是可以接受的,并且这种方法更为简洁和高效。

因此,你可以根据具体的需求选择使用哪种方式来比较Person对象的身高。如果需要精确表示并且可以承受一定的性能开销,可以选择使用BigDecimal;如果精度丢失不是关键问题,并且希望保持代码简洁和高效,可以选择使用Double.compare方法。

        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;
    }
}

posted on 2024-01-27 14:44  周政然  阅读(41)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3