前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何比较?Comparable还是Comparator

如何比较?Comparable还是Comparator

作者头像
naget
发布2019-07-03 15:38:20
3920
发布2019-07-03 15:38:20
举报
文章被收录于专栏:VegoutVegout

我家开了个小卖店,为了实现数字化管理,我准备写个后台程序来对所有货物进行管理。首先定义了这个实体类,这个类就是“货物”类,num指的是他的编号,s指他的名称或描述,data指他的进货日期。

代码语言:javascript
复制
public class Goods {
    int num;
    String s;
    Date date;
       public Goods(int num, String s, Date date) {
        this.num = num;
        this.s = s;
        this.date = date;
    }
    //getter setter
}

目前有一个需求,就是对所有货物进行排序。首先我想到了一个办法,就是直接实现Comparable接口,再实现接口定义的方法,在方法中完成货物的比较逻辑,虽然这样并不符合“开闭原则”,但我还是这么干了,于是这个类就变成了现在这个样子

代码语言:javascript
复制
public class Goods implements Comparable<Goods> {
    int num;
    String s;
    Date date;
    public Goods(int num, String s, Date date) {
        this.num = num;
        this.s = s;
        this.date = date;
    }
    @Override
    public int compareTo(Goods o) {
        if (this.num>o.num)return 1;
        else if (this.num==o.num) return 0;
        else  return -1;
    }
//getter setter
}

看一下测试类

代码语言:javascript
复制
public class Main {
    public static void main(String[] args) {
        Goods g1=new Goods(1,"可乐",new Date(System.currentTimeMillis()));
        Goods g2=new Goods(2,"面包",new Date(System.currentTimeMillis()+1000));
        Goods[] goodss = {g2,g1};
        Arrays.sort(goodss);
    }
}

比较逻辑中比较的是货物的编号,g1比g2大,则返回1,小则返回-1,否则返回0;完成了这个比较逻辑,就可以进行排序了,简单调用Arrays.sort()就可以完美完成货物的排序。Arrays.sort内部调用了如下代码

代码语言:javascript
复制
        if (length < INSERTIONSORT_THRESHOLD) {
            for (int i=low; i<high; i++)
                for (int j=i; j>low &&
                         ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
                    swap(dest, j, j-1);
            return;
        }

可以看到我们实现的方法compareTo()的调用,dest就是我们传入的goodss。就在我庆幸完成了任务时,我妈忽然嚷到“按编号排序有个啥子用啊???!!你是不是傻呀,进货日期赶紧改!!”哎,软件工程师(我就喜欢这么叫自己,傲娇脸)最烦的就是该需求了,但在老娘面前还是没脾气(说的好像在老板面前敢有脾气似的…)。于是我赶忙把compareTo中的比较对象换成了进货日期,完成任务后进入了“每日三省吾码”环节,这么写对嘛?还能怎样写?哪样写好呢?在思考一秒钟之后,嗯,还不行,哪天老娘又要按编号排,哪哪天又要改回来,我岂不是还得改来改去,于是乎,第二位主角登场Comparator

代码语言:javascript
复制
public class GoodsNumCompartor implements Comparator<Goods> {
    @Override
    public int compare(Goods o1, Goods o2) {
        if (o1.getNum()>o2.getNum())return 1;
        else if(o1.getNum()==o2.getNum())return 0;
        else return -1;
    }
}
public class GoodsDateCompartor implements Comparator<Goods> {
    @Override
    public int compare(Goods o1, Goods o2) {
        return o1.getDate().compareTo(o2.getDate());
    }
}

定义了两个比较器,以后需要用什么元素进行排序,就传入对应的比较器就可以了

代码语言:javascript
复制
Arrays.sort(goodss,new GoodsDateCompartor());
Arrays.sort(goodss,new GoodsNumCompartor());

源码中会调用我们的比较器

代码语言:javascript
复制
        if (length < INSERTIONSORT_THRESHOLD) {
            for (int i=low; i<high; i++)
                for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                    swap(dest, j, j-1);
            return;
        }

c就是我们传入的比较器,从起妈妈不会再难为我,老板不会再难为你。

结语

实现comparable接口或定义一个比较器都可实现自定义对象的比较,不同的是,comparable需要修改原本的类信息来加入比较的逻辑;而比较器的方式将类本身的定义和类比较的定义进行了分离,耦合性降低了,灵活性增加了,而且通过增加比价器,我们可以增加多种比较方式。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Vegout 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档