java comparator相等_详解Java中Comparable和Comparator接口的区别

详解Java中Comparable和Comparator接口的区别

发布于 2020-7-20|

复制链接

摘记: 详解Java中Comparable和Comparator接口的区别本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧。Comparable 简介 ..

详解Java中Comparable和Comparator接口的区别本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧。Comparable 简介Comparable 是排序接口。若一个类实现了Comparable接口,就意味着“该类支持排序”。  即然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序。此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中的元素,而不需要指定比较器。Comparable 定义Comparable 接口仅仅只包括一个函数,它的定义如下:

```java

package java.lang;

import java.util.*;

public interface Comparable {

public int compareTo(T o);

}

```

说明:假设我们通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。Comparator 简介Comparator 是比较器接口。我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。Comparator 定义Comparator 接口仅仅只包括两个个函数,它的定义如下:

```java

package java.util;

public interface Comparator {

int compare(T o1, T o2);

boolean equals(Object obj);

}

```

说明:(01) 若一个类要实现Comparator接口:它一定要实现compareTo(T o1, T o2) 函数,但可以不实现 equals(Object obj) 函数。为什么可以不实现 equals(Object obj) 函数呢? 因为任何类,默认都是已经实现了equals(Object obj)的。 Java中的一切类都是继承于java.lang.Object,在Object.java中实现了equals(Object obj)函数;所以,其它所有的类也相当于都实现了该函数。(02) int compare(T o1, T o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”。Comparator 和 Comparable 比较Comparable是排序接口;若一个类实现了Comparable接口,就意味着“该类支持排序”。而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。我们不难发现:Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。我们通过一个测试程序来对这两个接口进行说明。源码如下:

```java

import java.util.*;

import java.lang.Comparable;

/**

* @desc "Comparator"和“Comparable”的比较程序。

* (01) "Comparable"

* 它是一个排序接口,只包含一个函数compareTo()。

* 一个类实现了Comparable接口,就意味着“该类本身支持排序”,它可以直接通过Arrays.sort() 或 Collections.sort()进行排序。

* (02) "Comparator"

* 它是一个比较器接口,包括两个函数:compare() 和 equals()。

* 一个类实现了Comparator接口,那么它就是一个“比较器”。其它的类,可以根据该比较器去排序。

*

* 综上所述:Comparable是内部比较器,而Comparator是外部比较器。

* 一个类本身实现了Comparable比较器,就意味着它本身支持排序;若它本身没实现Comparable,也可以通过外部比较器Comparator进行排序。

*/

public class CompareComparatorAndComparableTest{

public static void main(String[] args) {

// 新建ArrayList(动态数组)

ArrayList list = new ArrayList();

// 添加对象到ArrayList中

list.add(new Person("ccc", 20));

list.add(new Person("AAA", 30));

list.add(new Person("bbb", 10));

list.add(new Person("ddd", 40));

// 打印list的原始序列

System.out.printf("Original sort, list:%s\n", list);

// 对list进行排序

// 这里会根据“Person实现的Comparable接口”进行排序,即会根据“name”进行排序

Collections.sort(list);

System.out.printf("Name sort, list:%s\n", list);

// 通过“比较器(AscAgeComparator)”,对list进行排序

// AscAgeComparator的排序方式是:根据“age”的升序排序

Collections.sort(list, new AscAgeComparator());

System.out.printf("Asc(age) sort, list:%s\n", list);

// 通过“比较器(DescAgeComparator)”,对list进行排序

// DescAgeComparator的排序方式是:根据“age”的降序排序

Collections.sort(list, new DescAgeComparator());

System.out.printf("Desc(age) sort, list:%s\n", list);

// 判断两个person是否相等

testEquals();

}

/**

* @desc 测试两个Person比较是否相等。

* 由于Person实现了equals()函数:若两person的age、name都相等,则认为这两个person相等。

* 所以,这里的p1和p2相等。

*

* TODO:若去掉Person中的equals()函数,则p1不等于p2

*/

private static void testEquals() {

Person p1 = new Person("eee", 100);

Person p2 = new Person("eee", 100);

if (p1.equals(p2)) {

System.out.printf("%s EQUAL %s\n", p1, p2);

} else {

System.out.printf("%s NOT EQUAL %s\n", p1, p2);

}

}

/**

* @desc Person类。

* Person实现了Comparable接口,这意味着Person本身支持排序

*/

private static class Person implements Comparable{

int age;

String name;

public Person(String name, int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public int getAge() {

return age;

}

public String toString() {

return name + " - " +age;

}

/**

* 比较两个Person是否相等:若它们的name和age都相等,则认为它们相等

*/

boolean equals(Person person) {

if (this.age == person.age && this.name == person.name)

return true;

return false;

}

/**

* @desc 实现 “Comparable” 的接口,即重写compareTo函数。

* 这里是通过“person的名字”进行比较的

*/

@Override

public int compareTo(Person person) {

return name.compareTo(person.name);

//return this.name - person.name;

}

}

/**

* @desc AscAgeComparator比较器

* 它是“Person的age的升序比较器”

*/

private static class AscAgeComparator implements Comparator {

@Override

public int compare(Person p1, Person p2) {

return p1.getAge() - p2.getAge();

}

}

/**

* @desc DescAgeComparator比较器

* 它是“Person的age的升序比较器”

*/

private static class DescAgeComparator implements Comparator {

@Override

public int compare(Person p1, Person p2) {

return p2.getAge() - p1.getAge();

}

}

}

```

下面对这个程序进行说明。a) Person类定义。如下:

```java

private static class Person implements Comparable{

int age;

String name;

...

/**

* @desc 实现 “Comparable” 的接口,即重写compareTo函数。

* 这里是通过“person的名字”进行比较的

*/

@Override

public int compareTo(Person person) {

return name.compareTo(person.name);

//return this.name - person.name;

}

}

```

说明:(01) Person类代表一个人,Persong类中有两个属性:age(年纪) 和 name“人名”。

(02) Person类实现了Comparable接口,因此它能被排序。b) 在main()中,我们创建了Person的List数组(list)。如下:

```java

// 新建ArrayList(动态数组)

ArrayList list = new ArrayList();

// 添加对象到ArrayList中

list.add(new Person("ccc", 20));

list.add(new Person("AAA", 30));

list.add(new Person("bbb", 10));

list.add(new Person("ddd", 40));

```

c) 接着,我们打印出list的全部元素。如下:

```java

// 打印list的原始序列

System.out.printf("Original sort, list:%s\n", list);

```

d) 然后,我们通过Collections的sort()函数,对list进行排序。由于Person实现了Comparable接口,因此通过sort()排序时,会根据Person支持的排序方式,即 compareTo(Person person) 所定义的规则进行排序。如下:

```java

// 对list进行排序

// 这里会根据“Person实现的Comparable接口”进行排序,即会根据“name”进行排序

Collections.sort(list);

System.out.printf("Name sort, list:%s\n", list);

```

e) 对比Comparable和Comparator我们定义了两个比较器 AscAgeComparator 和 DescAgeComparator,来分别对Person进行 升序 和 降低 排序。e.1) AscAgeComparator比较器它是将Person按照age进行升序排序。代码如下:

```java

/**

* @desc AscAgeComparator比较器

* 它是“Person的age的升序比较器”

*/

private static class AscAgeComparator implements Comparator {

@Override

public int compare(Person p1, Person p2) {

return p1.getAge() - p2.getAge();

}

}

```

e.2) DescAgeComparator比较器它是将Person按照age进行降序排序。代码如下:

```java

/**

* @desc DescAgeComparator比较器

* 它是“Person的age的升序比较器”

*/

private static class DescAgeComparator implements Comparator {

@Override

public int compare(Person p1, Person p2) {

return p2.getAge() - p1.getAge();

}

}

```

f) 运行结果运行程序,输出如下:

```java

Original sort, list:[ccc - 20, AAA - 30, bbb - 10, ddd - 40]

Name sort, list:[AAA - 30, bbb - 10, ccc - 20, ddd - 40]

Asc(age) sort, list:[bbb - 10, ccc - 20, AAA - 30, ddd - 40]

Desc(age) sort, list:[ddd - 40, AAA - 30, ccc - 20, bbb - 10]

eee - 100 EQUAL eee - 100

```

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/345088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 11:运行单文件程序和“ shebang”脚本

在Java 11中,对java启动器进行了增强,使其可以直接运行单文件源代码程序,而不必先对其进行编译。 例如,考虑以下仅添加其参数的类: import java.util.*; public class Add {public static void main(String[] args) …

update core.php 更新_PHP: 更新日志 - Manual

8.0.0The format character p has been added.Prior to this version, false was returned on failure.Prior to this version, false was returned on failure.These functions no longer return false on failure.callback 回调现在可以为空(nullable)。scale is now nullabl…

分布式事务 camel_使用Camel在Amazon上构建分布式工作流应用程序

分布式事务 camel带有SNS-SQS的管道 工作流由以动态条件确定的特定顺序执行的独立任务组成。 工作流通常代表业务流程,例如电子商务商店中的订单处理步骤。 Amazon Web Services提供了用于构建分布式和可伸缩工作流应用程序的各种工具。 构建此类应用程序的一种方法…

php登陆框_PHP 登录完成跳转上一访问页面

需求描述:访问网站页面时,有的页面需要授权才能访问,这时候就会要求用户登录,跳转到登录页面login.php,怎么实现登录后返回到刚才访问的页面。解决思路1:在跳转到登录页面之前要将当前访问页面的url保存到c…

比较Java REST文档框架

确定在记录REST API时选择哪种Java框架可能很麻烦。 在本博文中,我们将简要比较我们自己使用的REST Web服务的三种文档框架,以及它们如何与Spring框架(这是Foreach最常使用的Java框架)集成。 这些是RESTful API建模语言&#xff0…

php 获取文件最后几行,php获取文件的最后N行数据

本篇文章介绍的内容是php获取文件的最后N行数据,现在分享给大家,也可以给有需要的朋友一个参考GitHub源码代码是基于以下问题,给出的解决方案:用php写一个函数,获取一个文本文件最后$n行内容,要求尽可能效率…

jaVa游戏三国志英杰传,《三国志英杰传》到底是怎样的一款游戏

原标题:《三国志英杰传》到底是怎样的一款游戏介绍作为PC平台上经典的战棋策略类游戏,英杰传系列可谓把这一类型游戏在战略性和资源获取上的精髓发挥的淋漓尽致。系列初代的《三国志英杰传》诞生在1995年的DOS系统上,虽然我接触英杰传时已经是…

jvm 内存镜像_镜像镜像–使用反射在运行时查看JVM内部

jvm 内存镜像开发人员:Takipi会告诉您何时新代码在生产中中断– 了解更多 我们都习惯于在我们的日常工作中直接或通过利用反射的框架来运用反射。 它是Java和Scala编程的主要方面,它使我们使用的库可以与我们的代码进行交互,而无需对其进行硬…

【渝粤题库】广东开放大学 微信平台开发与应用 形成性考核 (2)

选择题 题目: 以下哪些功能是属于微信的? 题目: 认证过的订阅号的底部是否可以直接链接到外部链接? 题目: 下面哪些属于页面前端开发技术? 题目: 那种情况下的公众号可以申请微信支付&#xff1…

php微信小程序获取用户信息,微信小程序获取openid及用户信息的方法

本文主要介绍微信小程序如何获取openid及用户信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能帮助到大家。1. 获取openid1.1 获取code调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid…

【渝粤题库】广东开放大学 服务标准化 形成性考核

​👉关注我,看答案👈 选择题 题目:以下关于本课程终考的描述正确的是? 题目:以下哪种方式能判断已发布的形考是否都做了? 题目:作为专业方向课,本课程最后的总成绩应该达到多少才不影…

谁去过顽皮,谁去过尼斯? 圣诞老人为您提供Java 11建议!

有没有想过圣诞老人如何为世界各地的孩子们送上节日礼物? 有20亿个孩子,每个孩子都有自己的愿望清单,他会在24小时内完成。 这意味着每个孩子平均需要43微秒,他需要检查每个孩子是否顽皮或好。 您无需再怀疑了。 我会透露这个秘密…

php时间格式函数,PHP函数之日期时间函数date()使用详解_php基础_脚本

$ttime();echo date("Y-m-d H:i:s",$t);第一个参数的格式分别表示:a - "am" 或是 "pm"A - "AM" 或是 "PM"d - 几日,二位数字,若不足二位则前面补零; 如: "01" 至 "31"D - 星期几…

【渝粤题库】广东开放大学 物业财税管理基础 形成性考核

选择题 题目:企业将资金以购买债券、提供借款或商业信用等形式出借给其他单位,这是一种( )的财务关系。 题目:( )是指买卖双方成交后,在双方约定的未来某一特定的时日才交割的交易市…

【渝粤题库】广东开放大学 统计基础 形成性考核

选择题 题目: 对某城市工业企业未安装设备进行普查,总体单位是( )。 选择一项: 题目: 某地"国内生产总值”这一统计指标属于( )。 选择一项: 题目&…

java无符号 uuid,java实现无符号数转换、字符串补齐、md5、uuid、随机数示例

package com.hongyuan.test;import java.security.messagedigest;import java.security.nosuchalgorithmexception;import java.util.random;import java.util.uuid;/** 杂项(无符号数转换,字符串补齐,md5,uuid,随机数)*/public class sundrytest {//转成…

【渝粤题库】广东开放大学 质量管理 形成性考核

​👉关注我,看答案👈 选择题 题目:可以通过哪些形式登陆学校的课程平台进行学习? 题目:以下关于课程勋章的说法,哪些是“正确”的? 题目:在“疑难解答区”发帖时,哪种类型…

play框架配置 拦截器_如何使用Play框架为https配置SSL证书

play框架配置 拦截器我花了几个小时试图使它起作用,最后,问题是我自己没有使用keytool生成CSR(证书请求)。 当我尝试通过https访问Play时,我一直收到此错误: javax.net.ssl.SSLPeerUnverifiedException&a…

【渝粤题库】陕西师范大学100141大学英语(三)作业 (专升本、高起本)

交际与对话 针对每个对话中未完成的部分有4个选项,请从A、B、C、D四个选项中选出正确选项。 a. What do you think of the speech given by Professor Smith? b. . But I’m not particularly interested in the topic. A. Let me think about it. B. Not bad. C.…

webmin升级php,Webmin php-lib.pl修改

我已经将PHP版本更新到5.5.26。使用PHP 5.4,我使用FCGI的Apache配置是:AddHandler fcgid-script .phpAddHandler fcgid-script .php5使用新版本的PHP我需要把其他配置工作:SetHandler fcgid-script没关系,它的工作。我的问题是与W…