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

运行结果为:

0
1
-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));
}

看一下运行结果:

0
1
-1

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

在自己的项目中获取对象集合中如果在sql中没有进行预排序,可以在这儿进行排序,例如:

 List<PartAreaDto> partAreaDtoList = ruleService.getPartAreaList();
Collections.sort(partAreaDtoList, new Comparator<PartAreaDto>() {
@Override
public int compare(PartAreaDto o1, PartAreaDto o2) {
return o2.getAreaCode().compareTo(o1.getAreaCode());
}
});

 

Collections.sort这样比较以后 list集合就会按照areaCode 进行正序排列,如果是Collections.reverse()则会按照areaCode进行倒序排列。 

总结

总结一下,两种比较器Comparable和Comparator,后者相比前者有如下优点:

1、如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法

2、实现Comparable接口的方式比实现Comparator接口的耦合性要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修改。从这个角度说,其实有些不太好,尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。实际上实现Comparator接口的方式后面会写到就是一种典型的策略模式

当然,这不是鼓励用Comparator,意思是开发者还是要在具体场景下选择最合适的那种比较器而已。

Comparable和Comparator的区别的更多相关文章

  1. Java中Comparable和Comparator接口区别分析

    Java中Comparable和Comparator接口区别分析 来源:码农网 | 时间:2015-03-16 10:25:20 | 阅读数:8902 [导读] 本文要来详细分析一下Java中Comp ...

  2. Java中Comparable与Comparator的区别

    相同 Comparable和Comparator都是用来实现对象的比较.排序 要想对象比较.排序,都需要实现Comparable或Comparator接口 Comparable和Comparator都 ...

  3. Comparable和Comparator的区别&Collections.sort的两种用法

    在Java集合的学习中,我们明白了: 看到tree,可以按顺序进行排列,就要想到两个接口.Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造 ...

  4. 面试----java基础集合---------------------comparable和comparator 的区别

    comparable接口     是主要是用来自定义类存储在主要是TreeSet,TreeMap(键)集合中存储时,自定通过实现这种接口得到自然排序的功能. comparator 接口  是主要是用来 ...

  5. 浅谈Comparable与Comparator的区别

    平时进行自定义排序一直使用实现Comparable接口,一段时间后操作的时候居然发现有了个Comparator接口 上网差了些资料,总结笔记一下. 基本原理就是比较,底层是二叉树 比如是3,6,5,1 ...

  6. PAT——1055. 集体照 (比较comparable和comparator的区别)

    拍集体照时队形很重要,这里对给定的N个人K排的队形设计排队规则如下: 每排人数为N/K(向下取整),多出来的人全部站在最后一排: 后排所有人的个子都不比前排任何人矮: 每排中最高者站中间(中间位置为m ...

  7. 你能说说Java中Comparable和Comparator的区别吗

    之前面试中被问到这个问题,当时不屑(会)回答,下来特意查了查,整理如下. Java 中为我们提供了两种比较机制:Comparable 和 Comparator,二者都是用来实现对象的比较.排序. 下面 ...

  8. Comparable与Comparator的区别

    Java的Comparator和Comparable当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序. 一.Com ...

  9. Comparable 与 Comparator的区别

    Comparable & Comparator 都是用来实现集合中元素的比较.排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序 ...

随机推荐

  1. spring接收json格式的多个对象参数(变通法)

    两种方法 方法1 如果使用spring mvc同客户端通信,完全使用json数据格式,需要如下定义一个RequestMapping @Controller public class TestContr ...

  2. 【Android测试】【第十九节】Espresso——API详解

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5997557.html 前言 Espresso的提供了不少A ...

  3. Method Swizzling

    学习博客: http://www.cocoachina.com/ios/20160121/15076.html (这个作者太牛了,写了我一直想知道的类簇的swizz方法) 一. 一般的swizz 先给 ...

  4. MySQL 在 LIMIT 条件后注入

    from:https://rateip.com/blog/sql-injections-in-mysql-limit-clause/ 此方法适用于MySQL 5.x中,在limit语句后面的注入例如: ...

  5. [转载]Difference between <context:annotation-config> vs <context:component-scan>

    在国外看到详细的说明一篇,非常浅显透彻.转给国内的筒子们:-) 原文标题: Spring中的<context:annotation-config>与<context:componen ...

  6. dynamoDb aws config aws_access_key_id aws_secret_access_key golang

    how to set  aws_access_key_id awscfg := aws.NewConfig().WithRegion(config.Region).WithCredentials(cr ...

  7. 真机远程调试 ( IOS Android 以及微信,weex)

    1.以前cordova远程调试,Android的直接连接USB后,用chrome打开chrome://inspect网址 IOS的打开Safari的developer下. 这是因为cordova的we ...

  8. equals == 比较

    public class Equals{ public static void main(String[] args){ Interger n1=new Interger(47); Interger ...

  9. [SharePoint 2010] Modify lookup mapping with PowerShell

    SharePoint支持将列表保存成列表模板,但当列表包含Lookup字段时,通过模板创建的列表会丢失Lookup字段的信息. 通过PowerShell,可以修改Lookup字段的xml内容. Fun ...

  10. MOSS(Microsoft Office Sharepoint Server)升级2013遇到的PDF权限问题及解决方案

    最近公司MOSS从2007升级到了2013,遇到了一个很呕心的问题: 为了保护公司资料安全,我们一直使用RMS给文档增加权限(信息权限管理 (IRM)),只有公司内部员工可以阅读.RMS加权限的范围仅 ...