之前面试中被问到这个问题,当时不屑(会)回答,下来特意查了查,整理如下。

Java 中为我们提供了两种比较机制:Comparable 和 Comparator,二者都是用来实现对象的比较、排序。

下面分别对Comparable 和 Comparator做具体介绍并总结。


Comparable

Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现。

如果add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int,有三种情况:

  • 比较者大于被比较者,返回正整数

  • 比较者等于被比较者,返回0

  • 比较者小于被比较者,返回负整数

写个很简单的例子:

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

  • o1大于o2,返回正整数

  • o1等于o2,返回0

  • o1小于o3,返回负整数

写个很简单的例子:

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"来命名

总结

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

实现Comparable接口的方式比实现Comparator接口的耦合性要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修改。因此:

  • 对于一些普通的数据类型(比如 String, Integer, Double…),它们默认实现了Comparable 接口,实现了 compareTo 方法,我们可以直接使用。

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

不同之处:

个人感觉说出上文观点,这个提问就算回答完了,如果非要说不同之处,那就是:

  • Comparator位于java.util包下,而Comparable位于java.lang包下

  • 实现Comparable接口的方式比实现Comparator接口的耦合性要强

  • 等等………..

你能说说Java中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. Java中Comparable和Comparator的区别

    前言 最近复习遇到了这个问题,在此进行一个详细的记录,分享给大家. 两个接口的区别 包区别 Comparable接口是在java.lang下. Comparator接口是在java.util下. 使用 ...

  4. Java 中 Comparable 和 Comparator 比较

    Java 中 Comparable 和 Comparator 比较 目录: Comparable Comparator Comparable 和 Comparator比较 第二个例子 之 Compar ...

  5. Java 中 Comparable 和 Comparator 比较(转)

    转自http://www.cnblogs.com/skywang12345/p/3324788.html 本文,先介绍Comparable 和Comparator两个接口,以及它们的差异:接着,通过示 ...

  6. Java中Comparable和Comparator区别小结

    一.Comparable简介 Comparable是排序接口.若一个类实现了Comparable接口,就意味着该类支持排序.实现了Comparable接口的类的对象的列表或数组可以通过Collecti ...

  7. Java中Comparable和Comparator你知多少?

    前言: 我喜欢这种遨游在Java的世界里,精心研究学习新鲜事物的感觉,即便再小再细再微不足道的东西,也让我乐此不疲,同时我也更愿意将我所会的东西分享出来供大家学习以及方便自己日后回顾.好了,闲话不多说 ...

  8. java中Comparable和Comparator两种比较器的区别

    Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较 ...

  9. 【转载】Java中Comparable和Comparator比较

    [本文转自]http://www.cnblogs.com/skywang12345/p/3324788.html Comparable 简介 Comparable 是排序接口. 若一个类实现了Comp ...

随机推荐

  1. 微信小程序与用户交互

    微信小程序与用户交互 一.显示消息提示框 wx.showToast({属性名:属性值}) 自定义一个提示框,时间到了会自动关闭 wx.showToast({ title:"成功", ...

  2. Bran的内核开发教程(bkerndev)-02 准备工作

    准备工作   内核开发是编写代码以及调试各种系统组件的漫长过程.一开始这似乎是一个让人畏惧的任务,但是并不需要大量的工具集来编写自己的内核.这个内核开发教程主要涉及使用GRUB将内核加载到内存中.GR ...

  3. 渗透测试-基于白名单执行payload--Pcalua

    0x01 Pcalua简介 Windows进程兼容性助理(Program Compatibility Assistant)的一个组件. 说明:Pcalua.exe所在路径已被系统添加PATH环境变量中 ...

  4. vc++木马源码免杀一些常用方法

    1.字符串连接 ////////////////////////////////////////////////////////////把字符串"canxin"连接起来(字符串连接 ...

  5. 动画讲解TCP

    前言 TCP 三次握手过程对于面试是必考的一个,所以不但要掌握 TCP 整个握手的过程,其中有些小细节也更受到面试官的青睐. 对于这部分掌握以及 TCP 的四次挥手,小鹿将会以动画的形式呈现给每个人, ...

  6. caffe中softmax源码阅读

    (1) softmax函数                                      (1) 其中,zj 是softmax层的bottom输入, f(zj)是softmax层的top输 ...

  7. 『嗨威说』算法设计与分析 - 动态规划思想小结(HDU 4283 You Are the One)

    本文索引目录: 一.动态规划的基本思想 二.数字三角形.最大子段和(PTA)递归方程 三.一道区间动态规划题点拨升华动态规划思想 四.结对编程情况 一.动态规划的基本思想: 1.1 基本概念: 动态规 ...

  8. 基于SignalR的服务端和客户端通讯处理

    SignalR是一个.NET Core/.NET Framework的实时通讯的框架,一般应用在ASP.NET上,当然也可以应用在Winform上实现服务端和客户端的消息通讯,本篇随笔主要基于Sign ...

  9. Spring Cloud Alibaba 使用nacos 注册中心

    ### 背景 上一文我们讲到了如何去搭建注册中心,这一次我们讲述如何使用nacos作为注册中心 ### spring-cloud-alibaba-basis 创建基础依赖 首先我们创建一个spring ...

  10. 魏永明: MiniGUI的涅槃重生之路

    本文系转载,著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 魏永明 来源: 微信公众号linux阅码场(id: linuxdev) 本文背景 MiniGUI是最负盛名的 ...