专栏首页Vegout如何比较?Comparable还是Comparator

如何比较?Comparable还是Comparator

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

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接口,再实现接口定义的方法,在方法中完成货物的比较逻辑,虽然这样并不符合“开闭原则”,但我还是这么干了,于是这个类就变成了现在这个样子

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
}

看一下测试类

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内部调用了如下代码

        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

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

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

Arrays.sort(goodss,new GoodsDateCompartor());
Arrays.sort(goodss,new GoodsNumCompartor());

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

        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需要修改原本的类信息来加入比较的逻辑;而比较器的方式将类本身的定义和类比较的定义进行了分离,耦合性降低了,灵活性增加了,而且通过增加比价器,我们可以增加多种比较方式。

本文分享自微信公众号 - Vegout(t10244201),作者:naget

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-06-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 无向图

    今天的主角是无向图,顾名思义,无向图就是边没有方向的图。每当一个概念拿到程序中,总是需要抽象出一个数据结构来表示这个概念。那么,图怎么表示呢?表示图的这个数据结...

    naget
  • 使用bitmap进行大量数据的排序、判断存在与否

    使用bitmap主要是可以减少存储空间的使用,用一个bit来存储一个元素的状态。当我们需要在一亿个数中判断某个数是否存在时,我们不需要将这一亿个数同时放入内存。

    naget
  • 希尔排序

    如果上一篇初级排序算法中的插入排序你已经熟悉,那么今天的这个希尔排序对你来说就要简单一些。希尔排序,就是使用不同增量进行一遍一遍的插入排序的排序算法。首先,增量...

    naget
  • 偷懒新姿势,打造属于RecyclerView的万能适配器Adapter和ViewHolder

    前言 昨天开始接触江湖口碑很好的RecyclerView,事实上,我已经被她的强大所征服了!资源回收,数据绑定,布局显示,分割线,Item动画多个模块高度解耦...

    非著名程序员
  • 工作中常见的设计模式-策略模式

    最近准备学习下之前项目中用到的设计模式,这里代码都只展示核心业务代码,省略去大多不重要的代码。

    一枝花算不算浪漫
  • 剑指Offer-二叉树的深度

    package Tree; import java.util.LinkedList; import java.util.Queue; /** * 二叉树...

    武培轩
  • 挑战程序竞赛系列(38):4.1模运算的世界(1)

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    用户1147447
  • golang之递归

    超蛋lhy
  • 总结了一些指针易出错的常见问题(一)

      简介:计算机是如何从内存单元中存取数据的呢?从程序设计的角度看,有两种办法:一是通过变量名;二是通过地址。程序中声明的变量是要占据一定的内存空间的,例如,C...

    互联网金融打杂
  • 剑指Offer全解

    在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个...

    racaljk

扫码关注云+社区

领取腾讯云代金券