Comparable和Comparator的区别

来源:互联网 发布:anywhere软件源 编辑:程序博客网 时间:2024/06/12 23:20

Comparable

Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。如果开发者add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int,有三种情况:

1、比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数

2、比较者等于被比较者,那么返回0

3、比较者小于被比较者,那么返回负整数

写个很简单的例子:

复制代码
复制代码
public class Domain implements Comparable<Domain>{    private String str;    public Domain(String str)    {        this.str = str;    }    public int compareTo(Domain domain)    {        if (this.str.compareTo(domain.str) > 0)            return 1;        else if (this.str.compareTo(domain.str) == 0)            return 0;        else             return -1;    }        public String getStr()    {        return str;    }}
复制代码
复制代码
复制代码
复制代码
public static void main(String[] args)    {        Domain d1 = new Domain("c");        Domain d2 = new Domain("c");        Domain d3 = new Domain("b");        Domain d4 = new Domain("d");        System.out.println(d1.compareTo(d2));        System.out.println(d1.compareTo(d3));        System.out.println(d1.compareTo(d4));    }
复制代码
复制代码

运行结果为:

01-1

注意一下,前面说实现Comparable接口的类是可以支持和自己比较的,但是其实代码里面Comparable的泛型未必就一定要是Domain,将泛型指定为String或者指定为其他任何任何类型都可以----只要开发者指定了具体的比较算法就行。

 

Comparator

Comparator可以认为是是一个外比较器,个人认为有两种情况可以使用实现Comparator接口的方式:

1、一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较

2、一个对象实现了Comparable接口,但是开发者认为compareTo方法中的比较方式并不是自己想要的那种比较方式

Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int,有三种情况:

1、o1大于o2,返回正整数

2、o1等于o2,返回0

3、o1小于o3,返回负整数

写个很简单的例子,上面代码的Domain不变(假设这就是第2种场景,我对这个compareTo算法实现不满意,要自己写实现):

复制代码
复制代码
public class DomainComparator implements Comparator<Domain>{    public int compare(Domain domain1, Domain domain2)    {        if (domain1.getStr().compareTo(domain2.getStr()) > 0)            return 1;        else if (domain1.getStr().compareTo(domain2.getStr()) == 0)            return 0;        else             return -1;    }}
复制代码
复制代码
复制代码
复制代码
public static void main(String[] args){    Domain d1 = new Domain("c");    Domain d2 = new Domain("c");    Domain d3 = new Domain("b");    Domain d4 = new Domain("d");    DomainComparator dc = new DomainComparator();    System.out.println(dc.compare(d1, d2));    System.out.println(dc.compare(d1, d3));    System.out.println(dc.compare(d1, d4));}
复制代码
复制代码

看一下运行结果:

01-1

当然因为泛型指定死了,所以实现Comparator接口的实现类只能是两个相同的对象(不能一个Domain、一个String)进行比较了,因此实现Comparator接口的实现类一般都会以"待比较的实体类+Comparator"来命名


接下来我们模拟下在集合对象中对日期属性进行排序

一、实体类Step

复制代码
package com.ljq.entity;/** * 运号单流程 *  * @author Administrator *  */public class Step{    /** 处理时间 */    private String acceptTime = "";    /** 快件所在地点 */    private String acceptAddress = "";    public Step() {        super();    }    public Step(String acceptTime, String acceptAddress) {        super();        this.acceptTime = acceptTime;        this.acceptAddress = acceptAddress;    }    public String getAcceptTime() {        return acceptTime;    }    public void setAcceptTime(String acceptTime) {        this.acceptTime = acceptTime;    }    public String getAcceptAddress() {        return acceptAddress;    }    public void setAcceptAddress(String acceptAddress) {        this.acceptAddress = acceptAddress;    }}
复制代码

        

二、实现Comparator接口

复制代码
package com.ljq.entity;import java.util.Comparator;import java.util.Date;import com.ljq.util.UtilTool;/** * 对Step类进行排序 *  * @author Administrator * */public class StepComparator implements Comparator<Step>{    /**     * 如果o1小于o2,返回一个负数;如果o1大于o2,返回一个正数;如果他们相等,则返回0;     */    @Override    public int compare(Step o1, Step o2) {        Date acceptTime1=UtilTool.strToDate(o1.getAcceptTime(), null);        Date acceptTime2=UtilTool.strToDate(o2.getAcceptTime(), null);                //对日期字段进行升序,如果欲降序可采用before方法        if(acceptTime1.after(acceptTime2)) return 1;        return -1;    }}
复制代码

           

三、测试

复制代码
package junit;import java.util.Collection;import java.util.Collections;import java.util.List;import org.junit.Test;public class StepComparatorTest {    @Test    public void sort() throws Exception{        List<Step> steps=new ArrayList<Step>;        //对集合对象进行排序         StepComparator comparator=new StepComparator();        Collections.sort(steps, comparator);        if(steps!=null&&steps.size()>0){            for(Step step:steps){               System.out.println(step.getAcceptAddress());               System.out.println(step.getAcceptTime());            }        }    }}
复制代码

原创粉丝点击