• Java-比较器Comparable与Comparator(详解)




    前言

    本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!
    也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!让我们在成长的道路上互相学习,欢迎关注!

    一、背景

    在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间 的比较问题。

    二、实现对象排序的两种方式

    ⭕ 自然排序:java.lang.Comparable
    ⭕ 定制排序:java.util.Comparator

    1、方式一:自然排序(java.lang.Comparable

    Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。

    ⭕ 实现 Comparable的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj)方法的返回值来比较大小。如果当前对象this大于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回负整数,如果当前对象this等于形参对象obj,则返回零。

    ⭕ 实现Comparable接口的对象列表(和数组)可以通过 Collections.sortArrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。

    ⭕ 于类 C 的每一个 e1e2 来说,当且仅当 e1.compareTo(e2) == 0e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals 一致。建议(虽然不是必需的)最好使自然排序与 equals 一致。

    Comparable 的典型实现类:(默认都是从小到大排列的)

    序号实现类作用
    1String按照字符串中字符的Unicode值进行比较
    2Character按照字符的Unicode值来进行比较
    3数值类型对应的包装类以及BigIntegerBigDecimal按照它们对应的数值大小进行比较
    4Booleantrue对应的包装类实例大于 false 对应的包装类实例
    5Date、Time后面的日期时间比前面的日期时间大

    代码演示:

    public class Goods implements  Comparable{
    
        private String name;
        private double price;
    
        public Goods() {
        }
    
        public Goods(String name, double price) {
            this.name = name;
            this.price = price;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(double price) {
            this.price = price;
        }
    
        @Override
        public String toString() {
            return "Goods{" +
                    "name='" + name + '\'' +
                    ", price=" + price +
                    '}';
        }
    
        //指明商品比较大小的方式:按照价格从低到高排序,再按照产品名称从高到低排序
        @Override
        public int compareTo(Object o) {
    //        System.out.println("**************");
            if(o instanceof Goods){
                Goods goods = (Goods)o;
                //方式一:
                if(this.price > goods.price){
                    return 1;
                }else if(this.price < goods.price){
                    return -1;
                }else{
    //                return 0;
                   return -this.name.compareTo(goods.name);
                }
                //方式二:
    //          return Double.compare(this.price,goods.price);
            }
    //        return 0;
            throw new RuntimeException("传入的数据类型不一致!");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    2、方式二:定制排序(java.util.Comparator)

    ⭕ 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用Comparator 的对象来排序,强行对多个对象进行整体排 序的比较。

    ⭕ 重写compare(Object o1,Object o2)方法,比较o1o2的大小:
    如果方法返回正整数,则表示o1于o2
    如果返回0,表示相等;
    返回负整数,表示 o1小于o2

    ⭕ 可以将 Comparator 传递给 sort 方法(如 Collections.sortArrays.sort),从而允许在排序顺序上实现精确控制。

    ⭕ 还可以使用 Comparator 来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序.

    代码演示:

    @Test
        public void test3(){
            String[] arr = new String[]{"AA","CC","KK","MM","GG","JJ","DD"};
            Arrays.sort(arr,new Comparator(){
    
                //按照字符串从大到小的顺序排列
                @Override
                public int compare(Object o1, Object o2) {
                    if(o1 instanceof String && o2 instanceof  String){
                        String s1 = (String) o1;
                        String s2 = (String) o2;
                        return -s1.compareTo(s2);
                    }
    //                return 0;
                    throw new RuntimeException("输入的数据类型不一致");
                }
            });
            System.out.println(Arrays.toString(arr));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    三、两种排序方式的区别

    Comparable接口的方式一旦确定,保证Comparable接口实现类的对象在任何位置都可以比较大小

    Comparator接口属于临时性的比较

  • 相关阅读:
    java-php-python-贵州省高考本科志愿填报指导系统计算机毕业设计
    从0到1设计通用数据大屏搭建平台
    Hadoop生态之Hive(二)
    vue3组件篇 Breadcrum
    Google共码未来 与 C站 创造者的经历
    ROS1 LTS版本安装教程
    Pthread 并发编程(二)——自底向上深入理解线程
    Jupyter如何开启Debug调试功能
    替代try catch处理异常的优雅方式
    BUUCTF 被偷走的文件 1
  • 原文地址:https://blog.csdn.net/weixin_52533007/article/details/126534409