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

【数据结构】关于Java对象比较,以及优先级队列的大小堆创建你了解多少???

前言:

🌟🌟Hello家人们,这期讲解对象的比较,以及优先级队列堆,希望你能帮到屏幕前的你。

🌈上期博客在这里:http://t.csdnimg.cn/MSex7

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

目录

📚️1. PriorityQueue中插入对象

📚️2元素的比较

2.1基本类型的比较

2.2对象比较问题

1.通过比较运算符

2.通过equals比较

📚️3.对象的比较

3.1重写基类的equals方法

3.2基于Comparble接口类的比较 

3.3基于比较器进行比较

3.4三种比较方式

📚️4.PriorityQueue的比较方式

4.1PriorityQueue的比较

4.2PriorityQueue大小堆解决topK问题

📚️总结


📚️1. PriorityQueue中插入对象

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

代码如下:

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 TestPriorityQueue(){PriorityQueue<Card> p = new PriorityQueue<>();p.offer(new Card(1, "♠"));p.offer(new Card(2, "♠"));}public static void main(String[] args) {TestPriorityQueue();}
}

那么此时我们运行时就会抛出异常:

因为放置的元素必须要能够比较大小,不能插入无法比较大小的对象。在这里,小编给Card类初始化了它的大小,和花色使得在编译时,不知道该比较那个。

📚️2元素的比较

2.1基本类型的比较

在Java中基本数据类型可以直接进行比较,一般通过>,<或者==来进行判断,放回值为boolean类型,小编这里就不再过多解释,相信大家因该了解了。

2.2对象比较问题

1.通过比较运算符

代码如下:

        Student student=new Student(12,"zhangsan");Student student1=new Student(12,"zhangsan");System.out.println(student1==student);

此时输出的值为false;

因为在“==”在实质上是比较的两个对象的地址,很明显这两个同学并不是同一个地址的,他们两个都new了一个地址出来,所以该地输出为false。

2.通过equals比较

代码如下:

        Student student=new Student(12,"zhangsan");Student student1=new Student(12,"zhangsan");System.out.println(student1.equals(student));

此时输出为false;

在这里,我们可以通过内部原理进行解析:

对于用户实现自定义类型,都默认继承自Object类,而Object类中提供了equal方法,而==默认情况下调用的就是equal方法,但是该方法的比较规则是:没有比较引用变量引用对象的内容,而是直接比较引用变量的地址

内部原理代码如下:

在这里this为student1,因为是student1调用函数与另一个学生进行比较,此时student就为obj。那么结果到头来还是地址的比较,所以还是为不等false 。

📚️3.对象的比较

3.1重写基类的equals方法

代码如下:

class Student{public int age;public String name;public Student(int age,String name){this.age=age;this.name=name;}@Override                         //进行重写public boolean equals(Object o) {if (this == o) return true;if(o==null||!(o instanceof Student)){return false;}Student student=(Student) o;return age==student.age&&name==student.name;}
}

在这里第一个条件:如果是自己调用自己那么就一定相等

在这里第二个条件:如果括号里的对象是空的,或者不是student的子类,那么就不相等

在这里最后的情况:实现强转,并且通过调用其年龄,和名字进行比较,并返回,实现equals重写

覆写基类equal的方式虽然可以比较,但缺陷是:equal只能按照相等进行比较,不能按照大于、小于的方式进行比较 

3.2基于Comparble接口类的比较 

对用用户自定义类型,如果要想按照大小与方式进行比较时:在定义类时,实现Comparble接口即可,然后在类中重写compareTo方法。

代码如下:

class Card implements Comparable<Card>{public int rank;public String suit;public Card(int rank,String suit) {this.rank=rank;this.suit=suit;}public int compareTo(Card o){return rank-o.rank;}
}
public class test {public static void main(String[] args) {Card card=new Card(5,"♥");Card card1=new Card(5,"♥");System.out.println(card.compareTo(card1));}
}

在重写compareTo方法时,是通过两者的大小进行比较,返回如果是一个正数,那么前者比后者更大,反之如果为一个负数那么就是后者更大,为0那么表示两者相同。

3.3基于比较器进行比较

用户自定义比较器类,实现Comparator接口,并且重写Comparator中的compare方法

代码如下:

class Agecompare implements Comparator<Student>{public int compare(Student s1,Student s2){return s1.age-s2.age;}
}
class Namecompare implements Comparator<Student>{public int compare(Student s1,Student s2){return s1.name.compareTo(s2.name);}
}
public class test {public static void main(String[] args) {Agecompare agecompare=new Agecompare();Namecompare namecompare=new Namecompare();Student student2=new Student(12,"lisi");Student student3=new Student(12,"lisi");System.out.println(agecompare.compare(student2,student3));System.out.println(namecompare.compare(student2,student3));}
}

这里要单独定义类来实现接口,并且重写接口当中的方法,在进行比较时对定义的类进行实例化,并且通过对应对象调用重写的compare方法,然后传递参数即可。

注意:但是在用对像调用时,名字为string类不能够相减,此时string引用类型compareto方法进行比较。因为string实现了comparable接口,重写了compareto方法。

 

3.4三种比较方式

覆写的方法:
Object.equals

因为所有类都是继承自 Object 的,所以直接覆写即可,不过只能比较相等与否
Comparable.compareTo
需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于内部顺序
Comparator.compare
需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强

📚️4.PriorityQueue的比较方式

4.1PriorityQueue的比较

当我们实现了compareor接口,并且重写了内部方法后,在PriorityQueue中如何实现添加对象呢?

代码如下:

class Agecompare implements Comparator<Student>{public int compare(Student s1,Student s2){return s1.age-s2.age;}
}
public class test {public static void main(String[] args) {Agecompare agecompare=new Agecompare();PriorityQueue<Student> p=new PriorityQueue<>(agecompare);p.offer(student);p.offer(student1);System.out.println(p.peek());p.poll();System.out.println(p.peek());}
}

此时我们需要实例化实现接口的类,并将比较器的实例作为参数传入,此时就能够传入学生对象了,但是输出是学生对象的地址,并没有实际意义。

4.2PriorityQueue大小堆解决topK问题

大小堆的接口实现:

class MaxHeap implements Comparator<Integer>{  //创建大堆public int compare(Integer o1,Integer o2){return o2-o1;}
}
class MinHeap implements Comparator<Integer>{  //创建小堆public int compare(Integer o1,Integer o2){return o1-o2;}
}

思路:在需要输出前K个最小的数目时,我们要创建大根堆,前k个数字组成的大根堆,当后面数字与堆顶元素比较时(堆顶元素最大)如果小于堆顶元素,那么就删除堆顶元素,将更小的元素传入堆中,那么在遍历完数组后,前K个组成的堆中就是最小的元素。

 代码如下:

class MintTopK {public void mink(int[] array,int k){if(k<=0){return;}MaxHeap maxHeap=new MaxHeap();PriorityQueue<Integer> q=new PriorityQueue<>(maxHeap);//创建一个大根堆(前k个值)for (int i = 0; i < k; i++) {q.offer(array[i]);}//堆剩下的数据进行操作for (int i = k; i < array.length ; i++) {if(array[i]<q.peek()){q.poll();q.offer(array[i]);}}//开始输出前k个数for (int i = 0; i <k ; i++) {int ret=q.poll();System.out.print(ret+" ");}}
}public class test {public static void main(String[] args) {int[] array={1,4,3,2,9};MintTopK mintTopK=new MintTopK();mintTopK.mink(array,3);}
}

那么此时的输出就为3  2  1

📚️总结

 💬💬小编这期主要讲解了对象的比较方式,以及优先级队列如何进行对象的插入,以及大小堆的创建,实现topK问题的解决。

对于优先级队列看似是二叉树的内容,但是实质上是数组的运用,在进行对象的比较时,也可以从源码进行理解,每种比较方式都有好坏,主要还是看情况哦~~~

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!


                               💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

                                                         😊😊  期待你的关注~~~

相关文章:

【数据结构】关于Java对象比较,以及优先级队列的大小堆创建你了解多少???

前言&#xff1a; &#x1f31f;&#x1f31f;Hello家人们&#xff0c;这期讲解对象的比较&#xff0c;以及优先级队列堆&#xff0c;希望你能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;http://t.csdnimg.cn/MSex7 &#x1f308;感兴趣的小伙伴看一看小编主页&…...

HQChart使用教程101-创建内置键盘精灵

HQChart使用教程101-创建内置键盘精灵 键盘精灵步骤1. 创建键盘精灵实例2. 设置事件回调3. 初始化键盘精灵4. 设置码表数据5. 监听"keydown","mousedown" 交流QQ群HQChart代码地址键盘精灵源码 完整实例 键盘精灵 键盘精灵是一种便捷操作软件的功能工具&a…...

nginx基础配置

1. https配置 首先在nginx.conf中配置https 2. 重定向 rewrite ^/(.*)$ https://www.sxl1.com/$1 permanent;3. 自动索引 autoindex on;4. 缓存 Nginx expire缓存配置: 缓存可以降低网站带宽&#xff0c;加速用户访问location ~ .*\.(gif|jpg|png)$ {expires 365d;roo…...

怿星科技与您相约——2024 Testing Expo

汽车测试及质量监控博览会(中国)Testing Expo China-Automotive 怿星科技展位路线 届时欢迎莅临2057号展台&#xff01;...

mac本地搭建docker+k8s步骤

概览&#xff1a; * kubectl安装 * minikube安装 * dashboard安装 主机配置&#xff1a; * mac M2 &#xff08;arm架构&#xff09; 服务及版本概览&#xff1a; 服务名称版本 kubectl v1.29.2 Kubernetes v1.30.0 kicbase v0.0.44 dashboard v2.7.0 docker 26.…...

JS DOM、点击事件

JS DOM 加载事件onload js代码执行的时候&#xff0c;需要html&css的支持 onload在页面加载完之后执行 dom&#xff1a;用JS对html标签进行增删改查 元素节点获取 var name document.getElementById("userName"); var inputs document.getElementsByTagNam…...

长短期记忆网络(LSTM)预测模型及其Python和MATLAB实现

## 一、背景 长短期记忆&#xff08;Long Short-Term Memory, LSTM&#xff09;网络是由 Sepp Hochreiter 和 Jrgen Schmidhuber 在 1997 年提出的一种特殊的循环神经网络&#xff08;RNN&#xff09;结构。LSTM 旨在解决传统 RNN 在处理长序列数据时常见的梯度消失和梯度爆炸…...

C语言——操作符详解

目录 1.操作符的分类 2.原码、反码和补码 3.移位操作符 3.1 左移操作符 3.2 右移操作符 4.位操作符 4.1 按位与& 4.2 按位或| 4.3 按位异或^ ​编辑 4.4 按位取反~ 4.5 应用题 4.5.1 题目&#xff1a;不能创建临时变量&#xff0c;实现两个整数的交换 4.5.2 …...

【Linux】内核全量函数添加日志打印摸索

1、操作系统在空载时要把函数调用次数非常多的注释掉&#xff0c;这里打印时不能带进程名称&#xff0c;高执行概率函数不同进程执行到的概率也很高&#xff0c;不然操作业务会增加卡死的概率&#xff1b; 2、卡死一般是调用次数太多导致&#xff0c;会卡住操作系统十多秒&…...

24/8/17算法笔记 CQL算法离线学习

离线学习&#xff1a;不需要更新数据 CQL&#xff08;Conservative Q-Learning&#xff09;算法是一种用于离线强化学习的方法&#xff0c;它通过学习一个保守的Q函数来解决标准离线RL方法可能由于数据集和学习到的策略之间的分布偏移而导致的过高估计问题 。CQL算法的核心思想…...

C++第十一弹 -- STL之List的剖析与使用

文章索引 前言1. list的介绍2 list的使用2.1 list的构造函数2.2 iterator的使用2.3 list capacity2.4 list element access2.5 list modifiers 3. list的迭代器失效4. list与vector的对比总结 前言 本篇我们旨在探讨对于STL中list的使用, 下一篇我们将会对list进行底层剖析以及…...

物流快递外卖管理平台系统-计算机毕设Java|springboot实战项目

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…...

开源BaaS 平台介绍

以下是几款常见的开源后端平台&#xff0c;它们提供了用户管理、权限验证、文件存储、API 管理等类似的后端功能。 1. Parse Server 简介: Parse 是一个非常流行的开源后端服务平台&#xff0c;它最初由 Facebook 开发&#xff0c;后来开源。它支持用户管理、数据存储、文件存…...

分享一个基于python爬虫的“今日头条”新闻数据分析可视化系统(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…...

QT自定义信号槽

1.自定义信号槽 使用connect()可以让我们连接系统提供的信号和槽&#xff0c;同时也可以自定义信号槽。 例如以学生和老师构建类同时当老师触发信号下课同学收到信号执行“吃饭”这一动作代码示例 #include "SignalAndSlot.h" //Teacher Student 总框架…...

one-shot 序列图像红外小目标分割

one-shot 序列图像红外小目标分割 IEEE TRANSACTIONS ON GEOSCIENCE AND REMOTE SENSING 代码还未开源 GitHub - D-IceIce/one-shot-IRSTS few-shot&#xff1a;利用少量标注样本进行学习 one-shot: 属于few-shot的特殊情况&#xff0c;只用一个样本进行学习 zero-shot&am…...

JavaScript 单线程防阻塞的原理

JavaScript 是一种单线程语言,这意味着它一次只能执行一个任务。这种设计可能会导致一些问题,比如当遇到耗时的操作时,整个程序可能会被阻塞。为了解决这个问题,JavaScript 使用了事件循环和回调函数的机制,实现了非阻塞式的异步操作。 事件循环 JavaScript 有一个事件队列,用…...

Shell脚本发送邮件的详细步骤与配置方法?

Shell脚本发送邮件的进阶技巧&#xff1f;怎么配置Shell脚本发信&#xff1f; 使用Shell脚本发送邮件是一种高效的自动化手段&#xff0c;特别是在需要定期发送报告、通知或警告信息时。AokSend将详细介绍Shell脚本发送邮件的步骤与配置方法&#xff0c;帮助您更好地掌握这一技…...

如何把Phalcon 集成到PhpStorm里面

一 背景 按照上一篇文章里面写的Phalcon 创建项目过程中的一些坑, 最终我们在终端可以基于Phalcon命令创建对应的开发项目。但在这个过程中,存在一个问题:那就是写代码的时候,发现Phalcon对应的依赖提示都没有,如下: 从上面这个截图来看,就能发现,Phalcon的啥…...

python从入门到精通:循环语句

目录 前言 1、while循环的基础语法 2、while循环的嵌套 3、for循环的基础语法 range语句&#xff1a; for循环临时变量作用域&#xff1a; 4、for循环的嵌套 5、循环中断&#xff1a;break和continue 前言 循环普遍存在于日常生活中&#xff0c;同样&#xff0c;在程序中…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...