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

news2024/9/24 23:30:48

前言:

🌟🌟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问题的解决。

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

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


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

                                                         😊😊  期待你的关注~~~

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

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

相关文章

分享一个基于SpringBoot的物品代购系统的设计与实现(源码、调试、LW、开题、PPT)

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

从零开始学嵌入式技术之数字电路

一&#xff1a;数字电路基础 数字电路是现代科技和工程领域中不可或缺的基础。从计算机系统到通信设备&#xff0c;从家庭电子产品到工业自动化&#xff0c;数字电路无处不在&#xff0c;影响着我们的生活和工作。本章节旨在向读者介绍数字电路的基本概念、原理和应用&#xff…

迭代器失效

一、什么是迭代器失效 迭代器的主要作用就是让算法能够不用关心底层数据结构&#xff0c;其底层实际就是一个指针&#xff0c;或者是对指针进行了封装&#xff0c;比如&#xff1a;vector的迭代器就是原生态指针T* 。因此迭代器失效&#xff0c;实际就是迭代器底层对应指针所指…

Kubernetes之Probe探针

目录 存活、就绪和启动探针 存活探针&#xff08;Liveness Probe&#xff09; 就绪探针&#xff08;Readiness Probe&#xff09; 启动探针&#xff08;Startup Probe&#xff09; 检测方式&#xff1a; exec&#xff1a; HTTP GET&#xff1a; TCP Socket&#xff1a; …

linux DHCP和VSFTP原理与配置

目录 一、DHCP工作原理 1.1 了解DHCP服务 1.1.1 DHCP基本描述 1.1.2 使用DHCP的好处 1.1.3 DHCP的分配方式 1.2 DHCP的租约过程 1.3 使用DHCP动态配置主机地址 1.4 安装DHCP服务器 二、DHCP服务器的配置 2.1 实验环境准备 2.2 实验实战示列 三、DHCP客户端的使用 …

【数据结构】汇总八、排序算法

排序Sort 【注意】本章是 排序 的知识点汇总&#xff0c;全文1万多字&#xff0c;含有大量代码和图片&#xff0c;建议点赞收藏&#xff08;doge.png&#xff09;&#xff01;&#xff01; 【注意】在这一章&#xff0c;记录就是数据的意思。 排序可视化网站&#xff1a; D…

Python - PyQt5环境搭建与基本配置和使用教程

****前期准备&#xff1a;PyQt5以及其他组件的下载与安装 python的图形界面开发过程中&#xff0c;我们需要三个组件&#xff0c;分别是&#xff1a;PyQt5、pyqt5-tools、PyQt5Designer 一、安装 确保Python和pip已安装&#xff1a; PyQt5是基于Python的图形用户界面库&…

WEB渗透免杀篇-Bypass-AMSI

往期文章 WEB渗透免杀篇-加载器免杀-CSDN博客 WEB渗透免杀篇-分块免杀-CSDN博客 WEB渗透免杀篇-Powershell免杀-CSDN博客 WEB渗透免杀篇-Python源码免杀-CSDN博客 WEB渗透免杀篇-C#源码免杀-CSDN博客 WEB渗透免杀篇-MSFshellcode免杀-CSDN博客 WEB渗透免杀篇-Bypass-AMSI-…

【大模型从入门到精通28】开源库框架LangChain 语义搜索:高级检索策略2

这里写目录标题 利用元数据与自我查询检索器元数据作为上下文信息初始化环境并定义元数据导入必要的模块定义元数据属性 配置自我查询检索器执行带有自动元数据推断的查询实现上下文压缩设置环境导入必要的类 初始化压缩工具创建上下文压缩检索器检索压缩文档 利用元数据与自我…

Nginx--日志

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、Nginx日志介绍 nginx 有一个非常灵活的日志记录模式&#xff0c;每个级别的配置可以有各自独立的访问日志, 所需日志模块 ngx_http_log_module 的…

别等GPT-4o啦,国产「开源版」GPT-4o 来了!支持全模态、无障碍交流

夕小瑶科技说 原创 作者 | 谢年年 腾讯最近的多模态进展有点子“一路高歌”&#xff0c;先是腾讯元宝升级了一波多模态能力&#xff0c;就差把GPT-4o从榜一拉下来了。 最近&#xff0c;又搞了一个和GPT-4o对标的交互式多模态模型——VITA&#xff0c;而且率先开源了。 每次…

算法-IMM

trajectory-prediction程序的imm.cc中的以下代码的对应的算法原理在后面 void IMM_UKF::InputInteract() {if (std::isnan(model_pro_(0)) || std::isnan(model_pro_(1)) || std::isnan(model_pro_(2)))std::abort();if (model_pro_.sum() ! 0)model_pro_ / model_pro_.sum();…

模组卡死?五步排查法助你快速定位并解决问题!

直线模组是许多机械设备中不可或缺的组件&#xff0c;在使用过程中可能会遇到各种故障&#xff0c;卡死是模组运行过程中最常出现的现象。以下是一些常见的直线模组卡死解决方法&#xff1a; 1、模组内部可能积聚了灰尘、杂质等&#xff0c;这些物质在模组运行过程中可能进入关…

Windows系统下两个不同版本的java切换

前言&#xff1a;在电脑中&#xff0c;已经安装好了两个不同版本的java&#xff0c;为了使用CMD随意切换两个不同版本的java&#xff0c;我们通过创建批处理文件来达到目的。 假设目前电脑中存在的两个java版本分别是java8和java21。 首先&#xff0c;创建java8的批处理文件“j…

minio下载镜像地址及启动脚本

MinIO下载 | 中国镜像下载加速站https://dl.minio.org.cn/server/minio/release/linux-amd64/archive/ MinIO下载 | 中国镜像下载加速站https://dl.minio.org.cn/client/mc/release/linux-amd64/ 文档: 单节点单硬盘部署MinIO — MinIO中文文档 | MinIO Linux中文文档 启动脚…

leetcode刷题-动态规划part01

代码随想录动态规划part01|动态规划理论基础、 509. 斐波那契数、 70. 爬楼梯 、746. 使用最小花费爬楼梯 动态规划基础509. 斐波那契数70.爬楼梯746. 使用最小花费爬楼梯 动态规划基础 动规五部曲&#xff1a; dp数组以及下标的含义&#xff1a;dp[i][j] dp[i]递推公式dp数组…

大模型格局变天:Llama3.1诞生

一、Llama3.1的背景 北美时间7月23日&#xff0c;Meta公司&#xff08;原Facebook&#xff09;宣布了一项重大突破&#xff1a;开源模型Llama 3.1的正式发布。这一举措预示着AI技术的又一次飞跃&#xff0c;Llama 3.1有望成为迄今为止最强大的开源大型语言模型&#xff08;LLM&…

Startup-SBOM:一款针对RPM和APT数据库的逆向安全工具

关于Startup-SBOM Startup-SBOM是一款针对RPM和APT数据库的逆向分析与安全检测工具&#xff0c;该工具本质上是一个简单的 SBOM 实用程序&#xff0c;旨在提供正在执行的包的内部视图&#xff0c;可以帮助广大研究人员枚举所有软件包以及可执行文件、服务和版本。 该工具的流程…

Docker 部署loki日志 用于微服务

因为每次去查看日志都去登录服务器去查询相关日志文件&#xff0c;还有不同的微服务&#xff0c;不同日期的文件夹&#xff0c;超级麻烦&#xff0c;因为之前用过ELK&#xff0c;原本打算用ELK&#xff0c;在做技术调研的时候发现了一个轻量级的日志系统Loki&#xff0c;果断采…

【大模型从入门到精通29】开源库框架LangChain 语义搜索:高级检索策略3

这里写目录标题 实现上下文压缩与 MMR 的文档检索设置基于压缩的检索器与 MMR探索替代文档检索方法加载和准备文档实现 TF-IDF 和 SVM 检索器最佳实践结论理论问题实践问题 实现上下文压缩与 MMR 的文档检索 设置基于压缩的检索器与 MMR 上下文压缩的目标是通过关注与查询最相…