当前位置: 首页 > news >正文

Java - 对象的比较

一、问题提出

前面讲了优先级队列,优先级队列在插入元素时有个要求:插入的元素不能是null或者元素之间必须要能够进行比较,为了简单起见,我们只是插入了Integer类型,
在这里插入图片描述
那优先级队列中能否插入自定义类型对象呢?
在这里插入图片描述

class Card{public int rank; // 数值public String suit; // 花色public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}
}
public class TestDome {public static void main(String[] args) {PriorityQueue<Card> priorityQueue = new PriorityQueue<>();priorityQueue.offer(new Card(5,"♣"));priorityQueue.offer(null);System.out.println(priorityQueue);}
}

优先级队列底层使用堆,而向堆中插入元素时,为了满足堆的性质,必须要进行元素的比较,而此时Card是没有办
法直接进行比较的,因此抛出异常。
通过实践,我们发现在没有指定 某种排序规则时,是无法将自定义类型入队的。
至于 Comparable,可以参考这篇文章javaSE - 三个常用的接口(Comparable,Comparator,Cloneable)

回顾

关于 对象的比较来说:
1、equals 方法,比较的是对象,如果比较的两个对象不相同:返回 false,反之,返回true
2、比较大小
我们的 Comparable 和 compareTo 使用比较大小的。指定比较的方式

我们要去堆Card 这种类型的对象进行比较,那就要实现Comparable或者Comparator,然后指定比较的方式,进行比较
Card 这个类里面有rank 和 suit 两个属性,是根据rank 或者 suit 进行比较

方法一、实现Comparable 接口

例如:使用rank 进行比较
方法一: 实现Comparable 接口 【注意!实现结结构,是要重写接口内部的抽象方法的】

class Card implements Comparable<Card>{public int rank; // 数值public String suit; // 花色public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}@Overridepublic int compareTo(Card o) {return this.rank - o.rank;}@Overridepublic String toString() {return "Card{" +"rank=" + rank +", suit='" + suit + '\'' +'}';}
}
public class TestDome {public static void main(String[] args) {PriorityQueue<Card> priorityQueue = new PriorityQueue<>();priorityQueue.offer(new Card(5,"♣"));priorityQueue.offer(new Card(2,"♥"));System.out.println(priorityQueue);}}   

这里是引用

那么,问题来了。我们也没有看见 优先级队列调用 compareTo 啊?
这里我们就需要去看一下,PriorityQueue 的 原码。
既然,自定义类型的数据能放的进去,而且 其结果 是有序的。
那么,说明 offer 在添加 自定义元素时,肯定是比较了的。
所以,我们从 offer 入手。
在这里插入图片描述

方法二:创建一个比较器(类),用来实现 Comparator 接口。通过这个类,来确定比较的规则

方法一对类的倾入性太强了,也就是说,在Card这个类里面实现比较的方式,那这个比较的方式就不能改了,但是如果哪天我们不根据rank进行比较,先要通过suit进行比较,那这个累计就不能实现比较了
在这里插入图片描述
所以我们应该将比较的方式单独实现一个类,将不同的比较方式提出来,例如:
在这里插入图片描述

利用匿名内部类实现上面的Comparator ,就是利用匿名内部类试下比较器
在这里插入图片描述
使用 lambda 表达式 - 与上一种方法是等价的。
在这里插入图片描述

二、元素的比较

2.1、基本类型的比较

在Java中,基本类型的对象可以直接比较大小。

public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a > b);
System.out.println(a < b);
System.out.println(a == b);
char c1 = 'A';
char c2 = 'B';
System.out.println(c1 > c2);
System.out.println(c1 < c2);
System.out.println(c1 == c2);
boolean b1 = true;
boolean b2 = false;
System.out.println(b1 == b2);
System.out.println(b1 != b2);
}

在这里插入图片描述

2.2、对象的比较

class Card {public int rank; // 数值public String suit; // 花色public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}
} 
public class TestPriorityQueue {public static void main(String[] args) {Card c1 = new Card(1, "♠");Card c2 = new Card(2, "♠");Card c3 = c1;//System.out.println(c1 > c2); // 编译报错System.out.println(c1 == c2); // 编译成功 ----> 打印false,因为c1和c2指向的是不同对象//System.out.println(c1 < c2); // 编译报错System.out.println(c1 == c3); // 编译成功 ----> 打印true,因为c1和c3指向的是同一个对象}
}

c1、c2和c3分别是Card类型的引用变量,上述代码在比较编译时:
c1 > c2 编译失败
c1== c2 编译成功
c1 < c2 编译失败
从编译结果可以看出,Java中引用类型的变量不能直接按照 > 或者 < 方式进行比较。 那为什么可以比较?
因为:对于用户实现自定义类型,都默认继承自Object类,而Object类中提供了equal方法,而
默认情况下调
用的就是equal方法,但是该方法的比较规则是:没有比较引用变量引用对象的内容,而是直接比较引用变量的地
址,但有些情况下该种比较就不符合题意。

我们也可以重写equal方法:

class Card {public int rank; // 数值public String suit; // 花色public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}@Overridepublic String toString() {return "Card{" +"rank=" + rank +", suit='" + suit + '\'' +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Card card = (Card) o;return rank == card.rank && Objects.equals(suit, card.suit);}@Overridepublic int hashCode() {return Objects.hash(rank, suit);}
}public class TestDome {public static void main(String[] args) {Card card1 = new Card(5,"♥");Card card2 = new Card(5,"♥");System.out.println(card1.equals(card2));}}

在这里插入图片描述
注意: 一般覆写 equals 的套路就是上面演示的

  1. 如果指向同一个对象,返回 true
  2. 如果传入的为 null,返回 false
  3. 如果传入的对象类型不是 Card,返回 false
  4. 按照类的实现目标完成比较,例如这里只要花色和数值一样,就认为是相同的牌
  5. 注意下调用其他引用类型的比较也需要 equals,例如这里的 suit 的比较
    覆写基类equal的方式虽然可以比较,但缺陷是:equal只能按照相等进行比较,不能按照大于、小于的方式进行
    比较。

2.3、三种方式对比

在这里插入图片描述

相关文章:

Java - 对象的比较

一、问题提出 前面讲了优先级队列&#xff0c;优先级队列在插入元素时有个要求&#xff1a;插入的元素不能是null或者元素之间必须要能够进行比较&#xff0c;为了简单起见&#xff0c;我们只是插入了Integer类型&#xff0c; 那优先级队列中能否插入自定义类型对象呢&#xf…...

[算法]选择排序

目录 1、选择排序的实现 2、例子 3、代码实现 4、时间复杂度和空间复杂度 5、选择排序的缺点——不稳定性 1、选择排序的实现 选择排序就是每一轮选择最小的元素直接交换到左侧。这种排序的最大优势&#xff0c;就是省去了多余的元素交换。 2、例子 原始数组和选择排序的…...

dp模型——状态机模型C++详解

状态机定义状态机顾名思义跟状态有关系&#xff0c;但到底有什么关系呢。在实际解决的时候&#xff0c;通常把状态想成节点&#xff0c;状态的转换想成有向边的有向图&#xff0c;我们来举个例子。相信大家都玩过类似枪战的游戏&#xff08;没玩过的也听说过吧&#xff09;&…...

1.4 条件概率与乘法公式

1.4.1 条件概率在实际问题中&#xff0c;除了直接考虑某事件 B 发生的概率P(B)外,有时还会碰到这样的问题&#xff0c;就是“在事件A 已经发生的条件下,事件B 发生的概率”。一般情况下,后概率与前一概率不同&#xff0c;为了区别,我们常把后者称为条件概率&#xff0c;记为P(B…...

VITA/PYTHON/LUPA families

Image Sensor Group Top to Bottom Portfolio in Industrial Imaging Machine Vision • Factory automation and inspection • Robotic vision • Biometrics High-End Surveillance • Aerial Surveillance • Intelligent Traffic Systems (ITS) • Mapping Medical and Sc…...

ChatGPT概述:从模型训练到基本应用的介绍

ChatGPT概述&#xff1a;从模型训练到基本应用的介绍 目录 本文是对ChatGPT的由来、训练过程以及实际落地场景的解释&#xff0c;主要内容包括如下三个方面&#xff1a; 1、ChatGPT是什么 2、ChatGPT的原理 3、ChatGPT的思考 4、ChatGPT的应用 ChatGPT是什么 ChatGPT可能是近…...

C语言实现扫雷【详细讲解+全部源码】

扫雷的实现1. 配置运行环境2. 扫雷游戏的初步实现2.1 建立扫雷分布模块2.2 创建名为board的二维数组并进行棋盘初始化2.3 打印棋盘3. 接下来该讨论的事情3.1 布置雷3.2 排查雷3.3 统计坐标周围有几个雷4. 完整扫雷游戏的实现4.1 game.h4.2 game.c4.3 扫雷.c1. 配置运行环境 本游…...

Vue2.0开发之——购物车案例-Goods组件封装-商品名称和图片(46)

一 概述 循环渲染Goods组件为Goods组件封装title属性为Goods组件封装pic属性 二 循环渲染Goods组件 2.1 App.vue中导入Goods组件 import Goods from /components/Goods/Goods.vue2.2 App.vue中注册Goods组件 components: {Header,Goods}2.3 循环渲染每一个商品的信息 <…...

0201基础-组件-React

1 组件和模块 1.1 模块 对外提供特定功能的js程序&#xff0c;一般就是一个js文件 为什么拆分模块呢&#xff1f;随着业务逻辑增加&#xff0c;代码越来越多&#xff0c;越来越复杂。作用&#xff1a;复用js&#xff0c;简化js&#xff0c;提高js运行效率 1.2 模块化 当应用…...

论文笔记 | Conducting research in marketing with quasi-experiments

这篇论文是Journal of Marketing上的论文&#xff0c;讲了使用准实验来进行论文研究的一些事项。外生性识别的来源、几种准实验方法的注意点还有内生性的解决。 这篇论文对于准实验或者是平常论文的展开有一个非常友善的指导功能&#xff0c;可以阅读~ 摘要&#xff1a;本文旨…...

有关Android导览(Android Navigation component)

文章目录小结有关Android导览(Android Navigation component)碰到的问题参考小结 在使用Android导览(Android Navigation component)碰到很多问题。解决了一些问题&#xff0c;但是“Skipped xxx frames! The application may be doing too much work on its main thread”这样…...

01 C语言计算

C语言计算 1、变量 用途&#xff1a;需要存放输入的数据 定义格式&#xff1a;数据类型 变量名&#xff08;用于区分其他变量&#xff09; 变量名格式&#xff1a;只能由字母/下划线/数字构成&#xff0c;首位不能是数字&#xff1b;且变量名不能是标识符 **变量赋值和初始…...

java单元测试简介(基于SpringBoot)

java单元测试简介&#xff08;基于SpringBoot&#xff09;mockitomock创建mock对象的另一种方式&#xff1a;Mockverifystubbing(存根)Spy&#xff08;间谍&#xff09;mock 静态方法mockito在springboot mock中的实战mockito 通常&#xff0c;在我们写单测时&#xff0c;会遇…...

Linux常用命令操作

文件目录操作 查看文件列表 ls #输出列表信息 ls -l #输出详细列表信息 ls -a #输出隐藏文件 ls -la #输出包含的隐藏文件及详细信息 ll # ls-l的缩写rwx分别对应读取&#xff0c;写入&#xff0c;执行权限&#xff0c;前面有d代表是文件夹 创建文件 touch file.txt #创建…...

SpringCloud GateWay配置—TLS 和 SSL、Http超时配置

一、TLS 和 SSL网关可以按照通常的 Spring 服务器配置侦听 HTTPS 上的请求。 以下示例演示如何执行此操作&#xff1a;application.ymlserver:ssl:enabled: truekey-alias: scgkey-store-password: scg1234key-store: classpath:scg-keystore.p12key-store-type: PKCS12您可以将…...

python Django中的cookies和session会话保持技术

cookies和session都是为了保持会话状态而诞生的两个存储技术会话定义&#xff1a; 从打开浏览器访问一个网站&#xff0c;到关闭浏览器结束此次访问&#xff0c;称之为一次会话HTTP协议是无状态的&#xff0c;导致会话状态难以保持Cookies-定义 cookies是保存在客户端浏览器上的…...

vue3的v-model指令

1. 普通input输入框双向绑定 <template><!-- 1. 普通input输入框双向绑定 --><!-- 其实等价于&#xff1a;<input :modelValue"title" update:modelValue"newTitle>titlenewTitle"/> --><input type"text" v-mod…...

Matlab小波去噪——基于wden函数的去噪分析

文章目录一、问题描述二、代码问题1&#xff1a;原始信号加6分贝高斯白噪声问题2&#xff1a;确定合适的小波基函数问题3&#xff1a;确定最合适的阈值计算估计方法问题4&#xff1a;确定合适的分解层数问题5&#xff1a;实际信号去噪问题6&#xff1a;对比三、演示视频最后一、…...

分布式对象存储——Apache Hadoop Ozone

前言 本文隶属于专栏《大数据技术体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见大数据技术体系 1. 概述 Ozone是Apache Hadoop项目的子项目&#xf…...

Linux 和数据库笔记-03

今天主要内容数据库相关介绍数据库(软件)常见类型Navicat 工具基本使用常见的数据类型和约束(重点)SQL 语句的编写(表和数据)一. 数据库是什么?为什么学习数据库软件中产生的所有数据, 最终都要存储于数据库当中测试人员如果想要进行数据查询/数据校验, 就必须掌握对数据库的基…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...