目录
简介
Queue接口
Deque 接口
AbstractQueue 抽象类
LinkedList
ArrayDeque
PriorityQueue
前言-与正文无关
生活远不止眼前的苦劳与奔波,它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界中,我们往往容易陷入工作的漩涡,忘记了停下脚步,感受周围的世界。让我们一起提醒自己,要适时放慢脚步,欣赏生活中的每一道风景,享受与家人朋友的温馨时光,发现那些平凡日子里隐藏的幸福时刻。因为,这些点点滴滴汇聚起来的,才是构成我们丰富多彩生活的本质。希望每个人都能在繁忙的生活中找到自己的快乐之源,不仅仅为了生存而工作,更为了更好的生活而生活。
送你张美图!希望你开心!
集合可以看作是一种容器,用来存储对象信息。所有集合类都位于java.util包下,值得一提的是支持多线程的集合类位于java.util.concurrent包下。
Queue
队列,在 JDK 中有两种不同类型的集合实现:单向队列(AbstractQueue) 和 双端队列(Deque)
Queue 中提供了两套增加、删除元素的 API,当插入或删除元素失败时,会有两种不同的失败处理策略。
方法及失败策略 | 插入方法 | 删除方法 | 查找方法 |
---|---|---|---|
抛出异常 | add() | remove() | get() |
返回失败默认值 | offer() | poll() | peek() |
选取哪种方法的决定因素:插入和删除元素失败时,希望抛出异常
还是返回布尔值
add()
和 offer()
对比:
在队列长度大小确定的场景下,队列放满元素后,添加下一个元素时,add() 会抛出 IllegalStateException
异常,而 offer()
会返回 false
。
但是它们两个方法在插入某些不合法的元素时都会抛出三个相同的异常。
remove()
和 poll()
对比:
在队列为空的场景下, remove()
会抛出 NoSuchElementException
异常,而 poll()
则返回 null
。
get()
和peek()
对比:
在队列为空的情况下,get()
会抛出NoSuchElementException
异常,而peek()
则返回null
。
Deque
接口的实现非常好理解:从单向队列演变为双向队列,内部额外提供双向队列的操作方法即可:
Deque 接口额外提供了针对队列的头结点和尾结点操作的方法,而插入、删除方法同样也提供了两套不同的失败策略。除了add()
和offer()
,remove()
和poll()
以外,还有get()
和peek()
出现了不同的策略
AbstractQueue 类中提供了各个 API 的基本实现,主要针对各个不同的处理策略给出基本的方法实现,定义在这里的作用是让子类
根据其方法规范
(操作失败时抛出异常还是返回默认值)实现具体的业务逻辑。
LinkedList 在上面已经详细解释了,它实现了 Deque
接口,提供了针对头结点和尾结点的操作,并且每个结点都有前驱和后继指针,具备了双向队列的所有特性。
使用数组实现的双端队列,它是无界的双端队列,最小的容量是8
(JDK 1.8)。在 JDK 11 看到它默认容量已经是 16
了。
ArrayDeque
在日常使用得不多,值得注意的是它与 LinkedList
的对比:LinkedList
采用链表实现双端队列,而 ArrayDeque
使用数组实现双端队列。
ArrayDeque 作为栈时比 Stack 性能好,作为队列时比 LinkedList 性能好
由于双端队列只能在头部和尾部操作元素,所以删除元素和插入元素的时间复杂度大部分都稳定在 O(1)
,除非在扩容时会涉及到元素的批量复制操作。但是在大多数情况下,使用它时应该指定一个大概的数组长度,避免频繁的扩容。
PriorityQueue 基于优先级堆实现的优先级队列,而堆是采用数组实现:
文档中的描述告诉我们:该数组中的元素通过传入 Comparator
进行定制排序,如果不传入Comparator
时,则按照元素本身自然排序
,但要求元素实现了Comparable
接口,所以 PriorityQueue 不允许存储 NULL 元素。
PriorityQueue 应用场景:元素本身具有优先级,需要按照优先级处理元素
public static void main(String[] args) {
Student vip1 = new Student("张三", 1);
Student vip3 = new Student("洪七", 2);
Student vip4 = new Student("老八", 4);
Student vip2 = new Student("李四", 1);
Student normal1 = new Student("王五", 0);
Student normal2 = new Student("赵六", 0);
// 根据玩家的 VIP 等级进行降序排序
PriorityQueue queue = new PriorityQueue<>((o1, o2) -> o2.getScore().compareTo(o1.getScore()));
queue.add(vip1);queue.add(vip4);queue.add(vip3);
queue.add(normal1);queue.add(normal2);queue.add(vip2);
while (!queue.isEmpty()) {
Student s1 = queue.poll();
System.out.println(s1.getName() + "进入游戏; " + "VIP等级: " + s1.getScore());
}
}
public static class Student implements Comparable {
private String name;
private Integer score;
public Student(String name, Integer score) {
this.name = name;
this.score = score;
}
@Override
public int compareTo(Student o) {
return this.score.compareTo(o.getScore());
}
}
执行上面的代码可以得到下面这种有趣的结果,可以看到氪金
使人带来快乐。
VIP 等级越高(优先级越高)就越优先安排进入游戏(优先处理),类似这种有优先级的场景还有非常多,各位可以发挥自己的想象力。
PriorityQueue 总结:
PriorityQueue 是基于优先级堆实现的优先级队列,而堆是用数组维护的
PriorityQueue 适用于元素按优先级处理的业务场景,例如用户在请求人工客服需要排队时,根据用户的VIP等级进行 插队
处理,等级越高,越先安排客服。
章节结束各集合总结:(以 JDK1.8 为例)
数据类型 | 插入、删除时间复杂度 | 查询时间复杂度 | 底层数据结构 | 是否线程安全 |
---|---|---|---|---|
Vector | O(N) | O(1) | 数组 | 是(已淘汰) |
ArrayList | O(N) | O(1) | 数组 | 否 |
LinkedList | O(1) | O(N) | 双向链表 | 否 |
HashSet | O(1) | O(1) | 数组+链表+红黑树 | 否 |
TreeSet | O(logN) | O(logN) | 红黑树 | 否 |
LinkedHashSet | O(1) | O(1)~O(N) | 数组 + 链表 + 红黑树 | 否 |
ArrayDeque | O(N) | O(1) | 数组 | 否 |
PriorityQueue | O(logN) | O(logN) | 堆(数组实现) | 否 |
HashMap | O(1) ~ O(N) | O(1) ~ O(N) | 数组+链表+红黑树 | 否 |
TreeMap | O(logN) | O(logN) | 数组+红黑树 | 否 |
HashTable | O(1) / O(N) | O(1) / O(N) | 数组+链表 | 是(已淘汰) |
------------------------------------------与正文内容无关------------------------------------
如果觉的文章写对各位读者老爷们有帮助的话,麻烦点赞加关注呗!作者在这拜谢了!
混口饭吃了!如果你需要Java 、Python毕设、商务合作、技术交流、就业指导、技术支持度过试用期。请在关注私信我,本人看到一定马上回复!
这是我全部文章所在目录,看看是否有你需要的,如果遇到觉得不对地方请留言,看到后我会查阅进行改正。
A乐神-CSDN博客
关注在文章左上角,作者信息处。