来吧,一文彻底搞懂Java中的Comparable和Comparator
大家好,我是沉默王二,今天在逛 programcreek 的时候,我发现了一些专注细节但价值连城的主题。比如说:java 的 comparable 和 comparator 是兄弟俩吗?像这类灵魂拷问的主题,非常值得深入地研究一下。
comparable 和 comparator 是 java 的两个接口,从名字上我们就能够读出来它们俩的相似性:以某种方式来比较两个对象。但它们之间到底有什么区别呢?请随我来,打怪进阶喽!
01、comparable
comparable 接口的定义非常简单,源码如下所示。
public interface comparable<t> {
int compareto(t t);
}
如果一个类实现了 comparable 接口(只需要干一件事,重写 compareto()
方法),就可以按照自己制定的规则将由它创建的对象进行比较。下面给出一个例子。
public class cmower implements comparable<cmower> {
private int age;
private string name;
public cmower(int age, string name) {
this.age = age;
this.name = name;
}
@override
public int compareto(cmower o) {
return this.getage() - o.getage();
}
public static void main(string[] args) {
cmower wanger = new cmower(19,"沉默王二");
cmower wangsan = new cmower(16,"沉默王三");
if (wanger.compareto(wangsan) < 0) {
system.out.println(wanger.getname() + "比较年轻有为");
} else {
system.out.println(wangsan.getname() + "比较年轻有为");
}
}
}
在上面的示例中,我创建了一个 cmower 类,它有两个字段:age 和 name。cmower 类实现了 comparable 接口,并重写了 compareto()
方法。
程序输出的结果是“沉默王三比较年轻有为”,因为他比沉默王二小三岁。这个结果有什么凭证吗?
凭证就在于 compareto()
方法,该方法的返回值可能为负数,零或者正数,代表的意思是该对象按照排序的规则小于、等于或者大于要比较的对象。如果指定对象的类型与此对象不能进行比较,则引发 classcastexception
异常(自从有了泛型,这种情况就少有发生了)。
02、comparator
comparator 接口的定义相比较于 comparable 就复杂的多了,不过,核心的方法只有两个,来看一下源码。
public interface comparator<t> {
int compare(t o1, t o2);
boolean equals(object obj);
}
第一个方法 compare(t o1, t o2)
的返回值可能为负数,零或者正数,代表的意思是第一个对象小于、等于或者大于第二个对象。
第二个方法 equals(object obj)
需要传入一个 object 作为参数,并判断该 object 是否和 comparator 保持一致。
有时候,我们想让类保持它的原貌,不想主动实现 comparable 接口,但我们又需要它们之间进行比较,该怎么办呢?
comparator 就派上用场了,来看一下示例。
1)原封不动的 cmower 类。
public class cmower {
private int age;
private string name;
public cmower(int age, string name) {
this.age = age;
this.name = name;
}
}
(说好原封不动,getter/setter 吃了啊)
cmower 类有两个字段:age 和 name,意味着该类可以按照 age 或者 name 进行排序。
2)再来看 comparator 接口的实现类。
public class cmowercomparator implements comparator<cmower> {
@override
public int compare(cmower o1, cmower o2) {
return o1.getage() - o2.getage();
}
}
按照 age 进行比较。当然也可以再实现一个比较器,按照 name 进行自然排序,示例如下。
public class cmowernamecomparator implements comparator<cmower> {
@override
public int compare(cmower o1, cmower o2) {
if (o1.getname().hashcode() < o2.getname().hashcode()) {
return -1;
} else if (o1.getname().hashcode() == o2.getname().hashcode()) {
return 0;
}
return 1;
}
}
3)再来看测试类。
cmower wanger = new cmower(19,"沉默王二");
cmower wangsan = new cmower(16,"沉默王三");
cmower wangyi = new cmower(28,"沉默王一");
list<cmower> list = new arraylist<>();
list.add(wanger);
list.add(wangsan);
list.add(wangyi);
list.sort(new cmowercomparator());
for (cmower c : list) {
system.out.println(c.getname());
}
创建了三个对象,age 不同,name 不同,并把它们加入到了 list 当中。然后使用 list 的 sort()
方法进行排序,来看一下输出的结果。
沉默王三
沉默王二
沉默王一
这意味着沉默王三的年纪比沉默王二小,排在第一位;沉默王一的年纪比沉默王二大,排在第三位。和我们的预期完全符合。
03、到底该用哪一个呢?
通过上面的两个例子可以比较出 comparable 和 comparator 两者之间的区别:
- 一个类实现了 comparable 接口,意味着该类的对象可以直接进行比较(排序),但比较(排序)的方式只有一种,很单一。
- 一个类如果想要保持原样,又需要进行不同方式的比较(排序),就可以定制比较器(实现 comparator 接口)。
- comparable 接口在
java.lang
包下,而comparator
接口在java.util
包下,算不上是亲兄弟,但可以称得上是表(堂)兄弟。
举个不恰当的例子。我想从洛阳出发去北京看长城,体验一下好汉的感觉,要么坐飞机,要么坐高铁;但如果是孙悟空的话,翻个筋斗就到了。我和孙悟空之间有什么区别呢?孙悟空自己实现了 comparable 接口(他那年代也没有飞机和高铁,没得选),而我可以借助 comparator 接口(现代化的交通工具)。
总而言之,如果对象的排序需要基于自然顺序,请选择 comparable
,如果需要按照对象的不同属性进行排序,请选择 comparator
。
04、鸣谢
好了,各位读者朋友们,以上就是本文的全部内容了。能看到这里的都是最胖的程序员(不,最棒),升职加薪就是你了
相关文章:
-
-
请求筛选模块被配置为拒绝包含双重转义序列的请求(.net core程序的‘web.config’调整)
请求筛选模块被配置为拒绝包含双重转义序列的请求的.net core处理 ... [阅读全文] -
缓存中间件 缓存架构的实现(上) 前言 一眨眼,2019年就过去了。我希望从按照中间件,分别阐述一些常见的架构问题,以及解决方案。一方面这些问题与解... [阅读全文]
-
准备在MacBook上装一个独立运行MAT工具(Memory Analyzer)的版本,碰到了一点坑,mark一下。 ... [阅读全文]
-
1. 类也是对象 在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段。在Python中这一点仍然成立: 但是,Python中的类还远不止... [阅读全文]
-
属性property 1. 私有属性添加getter和setter方法 2. 使用property升级getter和setter方法 运行结果: 3... [阅读全文]
-
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
推荐阅读
-
来吧,一文彻底搞懂Java中最特殊的存在——null
-
一文彻底搞懂Java和JDK的版本命名问题
-
来吧,一文彻底搞懂Java中的Comparable和Comparator
-
【小家Java】聊聊Java中的比较器(排序):Comparable和Comparator;Spring中的Comparators和AnnotationAwareOrderComparator
-
Java中Comparable和Comparator接口的区别
-
java中Comparator和 Comparable的介绍及区别实例
-
Java中Comparable和Comparator的对比介绍(代码示例)
-
来吧,一文彻底搞懂Java中最特殊的存在——null
-
java中Comparator和 Comparable的介绍及区别实例
-
Java中Comparable和Comparator的对比介绍(代码示例)
发表评论