Java——比较器
引入的背景
我们知道基本数据类型的数据(除boolean类型外)需要比较大小的话,直接使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢?
在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
Java实现对象排序的方式有两种:
- 自然排序:java.lang.Comparable
- 定制排序:java.util.Comparator
自然排序:java.lang.Comparable
Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。
如果当前对象this大于形参对象obj,则返回正整数。
如果当前对象this小于形参对象obj,则返回负整数。
如果当前对象this等于形参对象obj,则返回零。
package java.lang;public interface Comparable{int compareTo(Object obj);
}
Comparable 的典型实现:(默认都是从小到大排列的)
- String:按照字符串中字符的Unicode值进行比较
- Character:按照字符的Unicode值来进行比较
- 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
- Boolean:true 对应的包装类实例大于 false 对应的包装类实例
- Date、Time等:后面的日期时间比前面的日期时间大
测试String
代码示例:
@Testpublic void test1(){//测试String已经写好的String [] a = new String[]{"Jack", "Tom", "Lucy"};//排序之前for (int i = 0; i < a.length; i++) {System.out.print(a[i]+"\t");}System.out.println();//使用Arrays进行排序Arrays.sort(a);//排序之后进行展示for (int i = 0; i < a.length; i++) {System.out.print(a[i]+"\t");}}
运行效果:

测试自己实现comparable接口
Product类
package cn.edu.chd.exer1;import java.util.Objects;public class Product implements Comparable{private String name;private double prices;//无参构造public Product() {}//全参构造public Product(String name, double prices) {this.name = name;this.prices = prices;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrices() {return prices;}public void setPrices(double prices) {this.prices = prices;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", prices=" + prices +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Product product = (Product) o;return Double.compare(product.prices, prices) == 0 && name.equals(product.name);}@Overridepublic int hashCode() {return Objects.hash(name, prices);}@Overridepublic int compareTo(Object o) {//如果是同一个对象,return 0if (this == o){return 0;}//两个对象比较的标准是:价格从小到大,价格一样的话,按照名字从小到大if (o instanceof Product){Product p = (Product)o;int v = Double.compare(this.prices, p.prices);
// return v;if (v != 0){return v;}//价格如果相同,名字按照从小到大return this.name.compareTo(p.name);}//手动抛异常throw new RuntimeException("类型不匹配");}
}
测试
//对不同对象的大小进行排序@Testpublic void test2(){//商品数组Product[] products = new Product[5];//全参构造器,在new对象时就对属性进行赋值products[0] = new Product("Huawei", 5999);products[1] = new Product("XiaoMi", 4999);products[2] = new Product("iPhone", 9999);products[3] = new Product("vivo", 3999);products[4] = new Product("Honer", 5999);System.out.println("排序之前");//排序之前的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}System.out.println("----------------------------------------------");//使用arrays进行排序Arrays.sort(products);System.out.println("排序之后");//排序后的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}}
运行效果

定制排序:java.util.Comparator
思考
- 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码(例如:一些第三方的类,你只有.class文件,没有源文件)
- 如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?(例如:我想要String按照字母从大到小的顺序排序,而不是默认的从小到大)
JDK在设计类库之初,也考虑到这种情况,所以又增加了一个java.util.Comparator接口。强行对多个对象进行整体排序的比较。
- 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
- 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。
Product类
package cn.edu.chd.exer2;import java.util.Objects;public class Product implements Comparable{private String name;private double prices;//无参构造public Product() {}//全参构造public Product(String name, double prices) {this.name = name;this.prices = prices;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrices() {return prices;}public void setPrices(double prices) {this.prices = prices;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", prices=" + prices +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Product product = (Product) o;return Double.compare(product.prices, prices) == 0 && name.equals(product.name);}@Overridepublic int hashCode() {return Objects.hash(name, prices);}@Overridepublic int compareTo(Object o) {//如果是同一个对象,return 0if (this == o){return 0;}//两个对象比较的标准是:价格从小到大,价格一样的话,按照名字从小到大if (o instanceof Product){Product p = (Product)o;int v = Double.compare(this.prices, p.prices);
// return v;if (v != 0){return v;}//价格如果相同,名字按照从小到大return this.name.compareTo(p.name);}//手动抛异常throw new RuntimeException("类型不匹配");}
}
按照商品的价格从低到高排序的comparator
@Testpublic void test1(){//new一个comparator接口的匿名实现类Comparator comparator = new Comparator() {//按照商品的价格从低到高排序@Overridepublic int compare(Object o1, Object o2) {if (o1 == o2){return 0;}if (o1 instanceof Product && o2 instanceof Product){//强转Product p1 = (Product) o1;Product p2 = (Product) o2;return Double.compare(p1.getPrices(), p2.getPrices());}throw new RuntimeException("类型不匹配");}};//商品数组Product[] products = new Product[5];//全参构造器,在new对象时就对属性进行赋值products[0] = new Product("Huawei", 5999);products[1] = new Product("XiaoMi", 4999);products[2] = new Product("iPhone", 9999);products[3] = new Product("vivo", 3999);products[4] = new Product("Honer", 5999);System.out.println("排序之前");//排序之前的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}System.out.println("----------------------------------------------");//将comparator对象作为参数进行传入,排序Arrays.sort(products, comparator);System.out.println("排序之后");//排序后的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}}
运行效果:

按照名称进行排序的comparator
//按照名称进行排序@Testpublic void test2(){//new一个comparator接口的匿名实现类Comparator comparator = new Comparator() {//按照商品的名称进行排序@Overridepublic int compare(Object o1, Object o2) {if (o1 == o2){return 0;}if (o1 instanceof Product && o2 instanceof Product){//强转Product p1 = (Product) o1;Product p2 = (Product) o2;return p1.getName().compareTo(p2.getName());}throw new RuntimeException("类型不匹配");}};//商品数组Product[] products = new Product[5];//全参构造器,在new对象时就对属性进行赋值products[0] = new Product("Huawei", 5999);products[1] = new Product("XiaoMi", 4999);products[2] = new Product("iPhone", 9999);products[3] = new Product("vivo", 3999);products[4] = new Product("Honer", 5999);System.out.println("排序之前");//排序之前的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}System.out.println("----------------------------------------------");//将comparator对象作为参数进行传入,排序Arrays.sort(products, comparator);System.out.println("排序之后");//排序后的遍历for (int i = 0; i < products.length; i++) {System.out.println(products[i]);}}
运行效果:

相关文章:
Java——比较器
引入的背景 我们知道基本数据类型的数据(除boolean类型外)需要比较大小的话,直接使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢? 在Java中经常会涉…...
【数据结构】初识泛型
文章目录 一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。这种限制对代码的束缚就会很大。所以我们引入了泛型。泛型,泛顾名思义就是广泛的意思。就是适用于许多许多类型。从代码上讲,就是对类型实现了参数…...
代码随想录--哈希--有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出: true 示例 2: 输入: s "rat", t "car" 输出: false 说明: 你可以假设字符串只包含小写字母。…...
MySQL——数据的增删改
2023.9.12 本章开始学习DML (数据操纵语言) 语言。相关学习笔记如下: #DML语言 /* 数据操作语言: 插入:insert 修改:update 删除:delete */#一、插入语句 #方式一:经典的插入 /* 语法: insert …...
云服务器与http服务器
如何与http服务器建立连接(客户端)? http请求设计格式: 例子: 发送http请求 http数据响应格式: 接收http服务器返回的数据需要进一步进行字符串处理操作,提取有用的数据。...
golang教程 beego框架笔记一
安装beego 安装bee工具 beego文档 # windos 推荐使用 go install github.com/beego/bee/v2master go get -u github.com/beego/bee/v2masterwindows使用安装bee工具时碰到的问题; 环境配置都没有问题,但是执行官网的命令:go get -u github…...
【深度学习】Mini-Batch梯度下降法
Mini-Batch梯度下降法 在开始Mini-Batch算法开始之前,请确保你已经掌握梯度下降的最优化算法。 在训练神经网络时,使用向量化是加速训练速度的一个重要手段,它可以避免使用显式的for循环,并且调用经过大量优化的矩阵计算函数库。…...
AI项目六:WEB端部署YOLOv5
若该文为原创文章,转载请注明原文出处。 一、介绍 最近接触网页大屏,所以就想把YOLOV5部署到WEB端,通过了解,知道了两个方法: 1、基于Flask部署YOLOv5目标检测模型。 2、基于Streamlit部署YOLOv5目标检测。 代码在…...
敲代码常用快捷键
1、代码拖动 PyCharm:按住 shiftalt鼠标选中某一区域来拖动,即可实现拖动这一区域至指定区域。Visual Studio Code (VSCode): - Windows/Linux:Alt 鼠标左键拖动 - MacOS:Option 鼠标左键拖动 IntelliJ IDEA: - Win…...
MyBatis: 分页插件PageHelper直接传递分页参数的用法
一、加分页插件依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.2.13</version></dependency>二、配置分页插件,并配置相关属性&a…...
Python基于Flask的高校舆情分析,舆情监控可视化系统
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 运行效果图 基于Python的微博大数据舆情分析,舆论情感分析可视化系统 系统介绍 微博舆情分析系…...
Python第一次作业练习
题目分析: """ 参考学校的相关规定。 对于四分制,百分制中的90分及以上可视为绩点中的4分,80 分及以上为3分,70 分以上为2分,60 分以上为1分; 五分制中的5分为四分制中的4分,4分为3分&#…...
InstallShield打包升级时不覆盖原有文件的解决方案
一个.NET Framework的Devexpress UI Windows Form项目,用的InstallShield,前些个版本都好好的,最近几个版本突然就没法更新了,每次更新的时候都覆盖不了原文件,而且这样更新后第一次打开程序(虽然是老程序&…...
服务器巡检表-监控指标
1、巡检指标 系统资源K8S集群NginxJAVA应用RabbitMQRedisPostgreSQLElasticsearchELK日志系统 2、巡检项 检查项目 检查指标 检查标准 系统资源 CPU 使用率 正常:<70% 低风险:≥ 70% 中风险:≥ 85% 高风险:≥ 9…...
无涯教程-JavaScript - DDB函数
描述 DDB函数使用双倍余额递减法或您指定的某些其他方法返回指定期间内资产的折旧。 语法 DDB (cost, salvage, life, period, [factor])争论 Argument描述Required/OptionalCostThe initial cost of the asset.RequiredSalvage 折旧结束时的价值(有时称为资产的残值)。 该…...
uniapp打包微信小程序。报错:https://api.weixin.qq.com 不在以下 request 合法域名列表
场景:在进行打包上传测试时,发现登录失效,但在测试中【勾选不效应合法域名】就可以。 出现原因:我在获取到用户code后,直接使用调用官方接口换取openid 解决方案: 可以把code带给后端,让他们返…...
stm32之31.iic
iic双线制。一根是SCL,作为时钟同步线;一根是SDA,作为数据传输线 SDN #include "iic.h"#define SCL PBout(8)#define SDA_W PBout(9) #define SDA_R PBin(9)void IIC_GPIOInit(void) {GPIO_InitTypeDef GPIO_InitStructure;//使能时钟GR…...
新的 ChatGPT 提示工程技术:程序模拟
即时工程的世界在各个层面上都令人着迷,并且不乏巧妙的方法来推动像 ChatGPT 这样的代理生成特定类型的响应。思想链 (CoT)、基于指令、N-shot、Few-shot 等技术,甚至奉承/角色分配等技巧都是充满提示的库背后的灵感,旨在满足各种需求。 在本文中,我将深入研究一项技术,据…...
【Python】爬虫基础
爬虫是一种模拟浏览器实现,用以抓取网站信息的程序或者脚本。常见的爬虫有三大类: 通用式爬虫:通用式爬虫用以爬取一整个网页的信息。 聚焦式爬虫:聚焦式爬虫可以在通用式爬虫爬取到的一整个网页的信息基础上只选取一部分所需的…...
leetcode分类刷题:队列(Queue)(三、优先队列用于归并排序)
1、当TopK问题出现在多个有序序列中时,就要用到归并排序的思想了 2、将优先队列初始化为添加多个有序序列的首元素的形式,再循环K次优先队列的出队和出队元素对应序列下个元素的入队,就能得到TopK的元素了 3、这些题目好像没有TopK 大用小顶堆…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
ArcGIS Pro+ArcGIS给你的地图加上北回归线!
今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等,设置经线、纬线都以10间隔显示。 2、需要插入背会归线…...
Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...
深入理解 React 样式方案
React 的样式方案较多,在应用开发初期,开发者需要根据项目业务具体情况选择对应样式方案。React 样式方案主要有: 1. 内联样式 2. module css 3. css in js 4. tailwind css 这些方案中,均有各自的优势和缺点。 1. 方案优劣势 1. 内联样式: 简单直观,适合动态样式和…...
