首页 > 编程语言 >[Java基础]PriorityQueue

[Java基础]PriorityQueue

时间:2024-09-28 22:49:31浏览次数:7  
标签:queue Java 基础 remove PriorityQueue add Student public

优先级队列

数据结构是堆

一. PriorityQueue

PriorityQueue 简介

继承关系

PriorityQueue 示例

二. Comparable 比较器

Compare 接口

三. Comparator 比较器

Comparator 接口

四. 底层原理

一. PriorityQueue
PriorityQueue 简介
PriorityQueue ,即优先级队列。优先级队列可以保证每次取出来的元素都是队列中的最小或最大的元素<Java优先级队列默认每次取出来的为最小元素>。

大小关系:元素的比较可以通过元素本身进行自然排序,也可以通过构造方法传入比较器进行比较。

继承关系

通过继承关系图可以知道 PriorityQueue 是 Queue 接口的一个实现类,而 Queue 接口是 Collection 接口的一个实现类,因此其拥有 Collection 接口的基本操作,此外,队列还提供了其他的插入,移除和查询的操作。每个方法存在两种形式:一种是抛出异常(操作失败时),另一种是返回一个特殊值(null 或 false)。

PriorityQueue 的 peek 和 element 操作的时间复杂度都为常数,add,offer,remove 以及 poll 的时间复杂度是 log(n)。

PriorityQueue 示例
impot java.util.PriorityQueue;

public class PriorityQueueTest{
public static void main(String[] args){
PriorityQueue queue = new PriorityQueue<>();
queue.add(11);
queue.add(22);
queue.add(33);
queue.add(55);
queue.add(44);
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
}
}
运行结果:

代码中我们依次添加11,22,33,55,44五个数据,然后进行删除,通过结果我们发现,每次删除的都为队列中最小元素,即体现了优先级队列。

结论:优先级队列默认每次获取队列最小的元素,也可以通过 comparator 比较器来自定义每次获取为最小还是最大。

注意:优先级队列中不可以存储 null。

二. Comparable 比较器
Compare 接口
public interface Comparable{
public int compareTo(T o);
}
该接口只存在一个 public int compareTo(T o); 方法,该方法表示所在的对象和 o 对象进行比较,返回值分三种:

1:表示该对象大于 o 对象
0:表示该对象等于 o 对象
-1:表示该对象小于 o 对象

需求:在优先级队列中存储对象学生,每个学生有 id,name 两个属性,并且使优先级队列每次按照学生的 id 从小到大取出。

代码示例:

Student 类:当前类实现了 Comparable 接口,即当前类提供了默认的比较方法。

public class Student implements Comparable{
    private int id;
    private String name;
    public Student(int id,String name,int age){
        this.id = id;
        this.name = name;
    }
    public int getId(){
        return id;
    }
    @Override
    public String toString(){
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
    @Override
    public int compareTo(Object o){
        Student o1 = (Student)o;
        return this.id - o1.id;
    }
}

PriorityQueueTest 类:

public class PriorityQueueTest {
public static void main(String[] args) {
PriorityQueue queue = new PriorityQueue<>();
queue.add(new Student(2,"Jack"));
queue.add(new Student(1,"Mary"));
queue.add(new Student(5,"Mcan"));
queue.add(new Student(4,"Scolt"));
queue.add(new Student(3,"Tina"));
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
}
}
运行结果:

三. Comparator 比较器
新需求:如果使优先级队列按照学生 id 从大到小取出呢?我们很快就会想到修改 Student 类的compareTo 方法,使 return o1.id - this.id;这样当然可以实现我们的新需求。但是有很多时候类的compareTo 方法是不能修改的,比如 JDK 给我们提供的源代码,在不修改 compareTo 方法的前提下实现需求,只能用 comparator 比较器了。

Comparator 接口
public interface Comparator{
int compare(T o1,T o2);
}
该接口只存在一个 int compare(T o1,T o2);方法,该方法需要参数是两个待比较的对象,返回结果是 int 类型:

1:表示 o1对象 大于 o2 对象
0:表示 o1对象 等于 o2 对象
-1:表示 o1对象 小于 o2 对象

public class PriorityQueueTest {
public static void main(String[] args) {
PriorityQueue queue = new PriorityQueue<>(new Comparator() {

        @Override
        public int compare(Student o1, Student o2) {
            return o2.getId() - o1.getId();
    }
})
queue.add(new Student(2, "Jack"));
queue.add(new Student(1, "Mary"));
queue.add(new Student(5, "Mcan"));
queue.add(new Student(4, "Scolt"));
queue.add(new Student(3, "Tina"));
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());

}
}
运行结果:

四. 底层原理
优先级队列是如何保证每次取出的是队列中最小(最大)的元素的呢?查看源代码,底层的存储结构为一个数组

transient Object[] queue;

表面上是一个数组结构,实际上优先队列采用的是堆的形式来进行存储的,通过调整小堆或大堆来保证每次取出的元素为队列中的最小或最大。

标签:queue,Java,基础,remove,PriorityQueue,add,Student,public
From: https://www.cnblogs.com/DCFV/p/18438542

相关文章

  • Java线程池内容记录
    线程池实现了对线程的复用,统一管理和维护线程,减少没有必要的开销。为什么要用线程池?为了提高效率,需要将一些业务采用多线程的方式去执行。几乎所有需要异步或并发执行任务的程序都可以使用线程池。线程池的概念和连接池是类似的。在Java集合中存储大量的线程对象,每次执行异......
  • 个位数统计Java
    1//给定一个k位整数1(0,,,d​k−1​​>0),请编写程序统计每种不同的个位数字出现的次数。例如:给定0,则有2个0,3个1,和1个3。2//输入格式3//每个输入包含1个测试用例,即一个不超过1000位的正整数。4//输出格式:5//对NN中每一种不同的个位数字,以D:M......
  • Java数据类型与运算符
    前言Java是一种广泛使用的编程语言,它以其“一次编写,到处运行”(WriteOnce,RunAnywhere,简称WORA)的理念而闻名。Java的学习将伴随着该文章展开!!一.数据类型Java的数据类型大体与C语音相类似,又有些许不同,且听我道来。基本数据类型分为整型,字符型,浮点型以及布尔类型! 1.1......
  • 华为OD机试2024年E卷-转骰子[200分]( Java | Python3 | C++ | C语言 | JsNode | Go )实
    题目描述骰子是一个立方体,每个面一个数字,初始为左1,右2,前3(观察者方向),后4,上5,下6,用123456表示这个状态,放置在平面上,可以向左翻转(用L表示向左翻转1次),可以向右翻转(用R表示向右翻转1次),可以向前翻转(用F表示向前翻转1次),可以向后翻转(用B表示向后翻转1次),可以逆时针旋转(......
  • 华为OD机试2024年E卷-矩阵匹配[200分]( Java | Python3 | C++ | C语言 | JsNode | Go )
    题目描述从一个N*M(N≤M)的矩阵中选出N个数,任意两个数字不能在同一行或同一列,求选出来的N个数中第K大的数字的最小值是多少。输入描述输入矩阵要求:1≤K≤N≤M≤150输入格式:NMKN*M矩阵输出描述N*M的矩阵中可以选出M!/N!种组合数组,每个组合......
  • 零基础学STM32(四)-LED灯闪烁实验
    本项目讲解所用工程均使用stm32f103C8T6芯片HAL库版本。原理讲解本节内容我们讲解点亮LED灯闪烁实验,简单来讲就是实现LED电平翻转实现LED灯亮灭的过程。我们点亮LED灯需要给LED输入一个高电平,熄灭LED灯则给LED灯输入一个低电平,将两个电平状态不断重复即可实现LED的闪烁。初......
  • 计算机毕业设计 智能旅游推荐平台的设计与实现 Java实战项目 附源码+文档+视频讲解
    博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌......
  • javaweb学习4
    今天主要学习了获取数据库连接的操作和mavenmaven导入mysql和druidjar包具体的jar坐标可以去这个网站找https://mvnrepository.com/<dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId......
  • 2024-2025-1 学号20241315《计算机基础与程序设计》第一周学习总结
    作业信息这个作业属于哪个课程2024-2025-1-计算机基础与程序设计)这个作业要求在哪里2024-2025-1计算机基础与程序设计第一周作业)这个作业的目标快速浏览一遍教材计算机科学概论(第七版),课本每章提出至少一个自己不懂的或最想解决的问题并在期末回答这些问题--......
  • 2024-2025 20241312 《计算机基础与程序设计》第一周学习总结
    作业信息|这个作业属于哪个课程|2024-2025-1-计算机基础与程序设计)|||这个作业要求在哪里|2024-2025-1计算机基础与程序设计第一周作业)|----||这个作业的目标|快速浏览一遍教材计算机科学概论(第七版),课本每章提出至少一个自己不懂的或最想解......