Comparable与Comparator的区别

Comparable与Comparator的区别

说明:对一组数据进行排序(升序或降序),在Java中有很多方式,可以自己手写排序算法(冒泡、快速、二叉树排序等),但一般都采用JDK为我们提供的现有的2个接口,Comparable和Comparator。

【二者的区别】

Comparable接口:

  • 可作为实现类的默认排序算法

  • Java中一些普通的数据类型(比如String,Integer,Double…),已经默认实现了Comprable接口,实现了compareTo方法,我们可以直接使用

Comprator接口:

  • 是一个类的扩展排序工具,采用策略模式

  • 对于一些自定义类,它们可能在不同情况下需要实现不同的比较策略,可以新创建Comparator接口,使用特定的Comparator实现进行比较

  • 可用于Collection.sort()、Arrays.sort()或者一些内部有序的集合(如SortedSet、SortedMap等)

【注意点】

  1. 同时存在,采用Comparator的规则进行比较

  2. Comparble接口的compareTo方法的返回值有3种情况:

  • e1.compareTo(e2) > 0 即 e1 > e2
  • e1.compareTo(e2) = 0 即 e1 = e2
  • e1.compareTo(e2) < 0 即 e1 < e2

通俗来说,如果一个实体类实现了Comparable接口来实现排序规则,使用一段时间后,如果想去改变这个排序规则,基于“开闭原则”对修改关闭对扩展开放,我们可以通过Comparator接口来实现新的排序规则让实体类去采纳,使用一段时间后,如果还想改变,再通过Comparator接口实现一个新的排序规则即可。不影响类的封装性,易于扩展。

【例子】

​ 实体类BookBean实现了Comparable接口,比较规则是按书价大小。将多个BookBean对象存储在List容器中,存储顺序是按照compareTo的规则。

//实体类
public class BookBean implements Comparable{
    //书名
    private String name;
    //书价
    private int count;
    //省略带参的构造函数、setter-getter方法、toString方法
    
    @Override
    public int compareTo(Object another) {
        if(another instanceof BookBean){
            BookBean anotherBook = (BookBean) another;
            int result;
            //这里按照书价比较
            result = getCount() - anotherBook.getCount();
        }
        return 0;
    }
}
public class Demo{
    public static void main(String[] args) {
        List<BookBean> list = new ArrayList<>();
        list.add(new BookBean("A",34));
        list.add(new BookBean("S",1));
        list.add(new BookBean("V",46));
        list.add(new BookBean("Q",26));

        //对list容器排序:按照内部存储对象BookBean的比较规则
        Collections.sort(list);
        //输出第一个元素
        System.out.println(list.get(0));
    }
}

测试结果:结果表明是按照书价大小来排序。

image-20210305114121343

针对上述例子,此时如果想改变排序规则,在不破坏原实体类的封装性的前提下,可实现Comparator接口制定新规则,在Collections.sort(list,comparator)中传入参数调用。

public class Demo2{
    public static void main(String[] args) {
        List<BookBean> list = new ArrayList<>();
        list.add(new BookBean("A",34));
        list.add(new BookBean("S",1));
        list.add(new BookBean("V",46));
        list.add(new BookBean("Q",26));

        //新增代码
        Comparator comparator1 = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof NewBookBean && o2 instanceof NewBookBean){
                    NewBookBean newBookBean1 = (NewBookBean) o1;
                    NewBookBean newBookBean2 = (NewBookBean) o2;
                    //这里还调用了 String 实现了Comparable 接口的 compareTo 方法,内部是通过 char 字符逐字比较使得
                    //排序方式:按书名的字符串升序排序
                    return newBookBean1.getName().compareTo(newBookBean2.getName());
                }
                return 0;
            }
        };


        //对list容器排序,传入comparator:按照内部存储对象BookBean的比较规则
        Collections.sort(list,comparator1);
        //Collections.sort(list);
        //输出第一个元素
        System.out.println(list.get(0));
    }
}

测试结果:结果表明是按照书名字符大小来排序的。

image-20210305114526683

【总结】

​ 这回知道二者的区别,以及怎么去使用了,开心!

参考文章:

1.https://blog.csdn.net/lck898989/article/details/78881330

2.https://blog.csdn.net/u011240877/article/details/53399019

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值