Java 中 Comparable 和 Comparator 比较

Comparable 简介

Comparable 是排序接口。

若一个类实现了Comparable接口,就意味着该类支持排序”。  即然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序

此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中的元素,而不需要指定比较器。

 

Comparable 定义

Comparable 接口仅仅只包括一个函数,它的定义如下:

package java.lang;
import java.util.*;public interface Comparable<T> {public int compareTo(T o);
}

说明:
假设我们通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。

 

Comparator 简介

Comparator 是比较器接口。

我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可

也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。

 

Comparator 定义

Comparator 接口仅仅只包括两个个函数,它的定义如下:

package java.util;public interface Comparator<T> {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相当于“外部比较器”。

 

我们通过一个测试程序来对这两个接口进行说明。源码如下:

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<Person> list = new ArrayList<Person>();// 添加对象到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<String>接口”进行排序,即会根据“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<Person>{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<String>” 的接口,即重写compareTo<T t>函数。*  这里是通过“person的名字”进行比较的*/@Overridepublic int compareTo(Person person) {return name.compareTo(person.name);//return this.name - person.name;}}/*** @desc AscAgeComparator比较器*       它是“Person的age的升序比较器”*/private static class AscAgeComparator implements Comparator<Person> {@Override public int compare(Person p1, Person p2) {return p1.getAge() - p2.getAge();}}/*** @desc DescAgeComparator比较器*       它是“Person的age的升序比较器”*/private static class DescAgeComparator implements Comparator<Person> {@Override public int compare(Person p1, Person p2) {return p2.getAge() - p1.getAge();}}}

运行程序,输出如下:

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

转发:https://www.cnblogs.com/skywang12345/p/3324788.html

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

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

相关文章

spgridview的过滤功能回调时发生错误~

代码中启用了过滤功能&#xff0c; 但当点击过滤的列时发生错误&#xff1a; error: spgridview_filtercallbackerrorhandler() was called - result 回调时发生错误... 详细见&#xff1a; HTML代码&#xff1a; AllowFiltering"True"FilterDataFields",Name,,…

web---SSL/TSL

对称加密 加密算法秘钥&#xff08;双方持有相同的秘钥&#xff09;&#xff0c;A使用加密算法秘钥加密文件&#xff0c;B使用加密算法秘钥解密文件&#xff1b; 演示一个对称加密RC4算法 注意&#xff1a;RC4加密是有漏洞的 明文和秘钥进行异或得到密文&#xff0c;密文和秘钥…

讨论了好久的问题,IE、Firefox下CSS图片垂直居中的问题

通过百度和谷歌找了好久都没找着一个合适的方法。以下是自己找出的一种方法&#xff0c;自认为还可以&#xff0c;而且&#xff0c;也方便简单。IE:当容器为div,或者tr,只要把容器的Css属性line-height设置成容器的高度就行了.当容器为a,且容器的css属性display为inline-block或…

Nginx----实现https站点

1、首先给域名设置证书&#xff0c;可以去阿里云购买 1、下载自动化脚本 目的&#xff1a;帮我们自动在nginx配置中添加证书 yum install python2-certbot-nginx2、输入命令 certbot --nginx --nginx-server-root/usr/local/openresty/nginx/conf/ -d zy.com 选择我们的url请求…

TCP/IP四层模型和OSI七层模型的概念

TCP/IP四层模型 TCP/IP是一组协议的代名词&#xff0c;它还包括许多协议&#xff0c;组成了TCP/IP协议簇。TCP/IP协议簇分为四层&#xff0c;IP位于协议簇的第二层(对应OSI的第三层)&#xff0c;TCP位于协议簇的第三层(对应OSI的第四层)。 TCP/IP通讯协议采用了4层的层级结构&…

setsockopt()用法(转载)

1. 如果在已经处于 ESTABLISHED状态下的socket(一般由端口号和标志符区分&#xff09;调用 closesocket&#xff08;一般不会立即关闭而经历TIME_WAIT的过程&#xff09;后想继续重用该socket&#xff1a; BOOL bReuseaddrTRUE; setsockopt(s,SOL_SOCKET ,…

Nginx----OpenResty

概要 OpenResty是一个基于Nginx与Lua的高性能Web平台&#xff0c;其内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。OpenRestye通过汇聚各种设计精良的Nginx模块&#xff08;主要由O…

《深入浅出Google Android》即将隆重上市!

《深入浅出 Google Android 》 作者在线答疑活动开始啦 &#xff1a;http://www.hiapk.com/bbs/forum-41-1.html 随着越来越多的手机 厂商和移动运营商加入了开放手机联盟&#xff0c; Android 平台 越来越受到广大开发 者的关注和推崇。 本书是是国内最早的 And…

MySQL两种引擎

Innodb引擎概述 Innodb引擎提供了对数据库ACID事务的支持&#xff0c;并且实现了SQL标准的四种隔离级别。该引擎还提供了行级锁和外键约束&#xff0c;它的设计目标是处理大容量数据库系统&#xff0c;它本身其实就是基于MySQL后台的完整数据库系统&#xff0c;MySQL运行时Inno…

公钥基础设施PKI体系介绍

PKI(Pubic Key Infrastructure)是一种遵循标准的利用公钥加密技术为电子商务的开展提供一套安全基础平台的技术和规范。用户可利用PKI平台提供的服务进行安全通信。 使用基于公钥技术系统的用户建立安全通信信任机制的基础是&#xff1a;网上进行的任何需要安全服务的通信都是建…

Flag counter被博客园禁了的解决方法

突然发现Flag counter展示不出来 一开始还以为是网速的问题&#xff0c;后来搜了搜才知道博客园把Flag counter禁了....之前的访问量全没了5555&#xff08;虽然也没多少&#xff09; 只好换一个记录访问量的好了&#xff1a;https://clustrmaps.com/ 进去之后创建账户 把网址贴…

ORM是什么?如何理解ORM

一、ORM简介 对象关系映射&#xff08;Object Relational Mapping&#xff0c;简称ORM&#xff09;模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说&#xff0c;ORM是通过使用描述对象和数据库之间映射的元数据&#xff0c;将程序中的对…

oracle调整Lock_sga参数而不使用虚拟内存

由于几乎所有的操作系统都支持虚拟内存&#xff0c;所以即使我们使用的内存小于物理内存&#xff0c;也不能避免操作系统将SGA换到虚拟内存&#xff08;SWAP&#xff09;。所以我们可以尝试使得SGA锁定在物理内存中不被换到虚拟内存中&#xff0c;这样减少页面的换入和换出&…

Nginx----高级

Nginx请求流程 Nginx进程结构 Nginx有两种进程结构&#xff0c;一种是单进程&#xff08;可以用于测试&#xff09;&#xff0c;一种是多进程&#xff08;用于生产&#xff0c;默认&#xff09; Nginx会按需同时运行多个进程&#xff1a;一个主进程(master)和几个工作进程(work…

基于Zookeeper的分布式锁

实现分布式锁目前有三种流行方案&#xff0c;分别为基于数据库、Redis、Zookeeper的方案&#xff0c;其中前两种方案网络上有很多资料可以参考&#xff0c;本文不做展开。我们来看下使用Zookeeper如何实现分布式锁。 什么是Zookeeper&#xff1f; Zookeeper&#xff08;业界简…

诗歌rials 之RJS的tips

一些RJS的tips ruby代码 # do_magic.rjs page[:reviews].toggle page[:review_name].value "this is cool" page << "if ($(review_name).value foo) (" page.alert(hi foo!) page << ")" page.select("#reviews…

web----epoll实现原理

epoll可以用单进程单线程实现高并发 首先我们可以实现单进程单线程实现高并发&#xff08;模拟非阻塞IO请求&#xff09; 服务端 //服务端 public class BlockNIOServer {public static void main(String[] args) throws IOException, InterruptedException {//获取通道ServerS…

索引的分类

注意&#xff1a;索引是在存储引擎中实现的&#xff0c;也就是说不同的存储引擎&#xff0c;会使用不同的索引。MyISAM和InnoDB存储引擎&#xff1a;只支持BTREE索引&#xff0c;也就是说默认使用BTREE&#xff0c;不能够更换。MEMORY/HEAP存储引擎&#xff1a;支持HASH和BTREE…

web----tcp三次握手

1、首先为什么需要握手 首先我们看一下TCP报文段的结构 TCP报文段中的窗口这16位字段部分&#xff0c;这里窗口的作用就是为了实现流量的控制&#xff0c;为什么会有流量的控制的引入&#xff1f;&#xff1f;&#xff1f;它是这样来的&#xff1a;若是发送方发送数据的速度大于…

诗歌rails 之自定义Helper模块

关键字: Rails Helper Rails默认为每个controller指定一个helper&#xff0c;所有的helper都放在app/helpers目录下 但是有些Helper我们希望是全局共享的&#xff0c;一般我们将这些Helper方法都扔在ApplicationHelper模块里 其实我们可以在app/helpers目录下建立我们自定义的H…