1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-08-10 00:41:37 +08:00

Compare commits

...

10 Commits

Author SHA1 Message Date
Guide
a4f6e01ba4
Merge pull request #2110 from huyangdev/main
[docs fix] Issue #2109
2023-08-02 21:11:46 +08:00
Guide
6559ceccbb
Merge pull request #2108 from JacketFu/main
update linkedhashmap-source-code.md
2023-08-02 21:03:20 +08:00
Guide
6f17dab346
Merge pull request #2107 from Smileslime47/patch-1
队列部分补充双端队列和优先队列
2023-08-02 20:54:11 +08:00
Guide
211bfd6e44
Merge pull request #2106 from yuanrui01/patch-1
Update java16.md
2023-08-02 20:52:54 +08:00
hy
c188cb6fc7 [docs fix] Issue #2109 2023-08-02 16:52:20 +08:00
jun
045cef80d3 update linkedhashmap-source-code.md 2023-08-02 10:51:23 +08:00
fu
11e30decfe
Merge branch 'Snailclimb:main' into main 2023-08-02 10:42:30 +08:00
jun
7efbe3a468 update linkedhashmap-source-code.md 2023-08-02 10:39:56 +08:00
Smile slime 47
70d67defb4
队列部分补充双端队列和优先队列 2023-08-02 09:40:04 +08:00
yuanrui
11c75cc9a2
Update java16.md
文字修正
2023-08-02 00:33:55 +08:00
4 changed files with 26 additions and 5 deletions

View File

@ -297,12 +297,32 @@ myStack.pop();//报错java.lang.IllegalArgumentException: Stack is empty.
1. 可以设置一个标志变量 `flag`,当 `front==rear` 并且 `flag=0` 的时候队列为空,当`front==rear` 并且 `flag=1` 的时候队列为满。
2. 队列为空的时候就是 `front==rear` 队列满的时候我们保证数组还有一个空闲的位置rear 就指向这个空闲位置,如下图所示,那么现在判断队列是否为满的条件就是:`(rear+1) % QueueSize==front`
#### 4.2.3 双端队列
**双端队列 (Deque)** 是一种在队列的两端都可以进行插入和删除操作的队列,相比单队列来说更加灵活。
一般来说,我们可以对双端队列进行 `addFirst``addLast``removeFirst``removeLast` 操作。
#### 4.2.4 优先队列
**优先队列 (Priority Queue)** 从底层结构上来讲并非线性的数据结构,它一般是由堆来实现的。
1. 在每个元素入队时,优先队列会将新元素其插入堆中并调整堆。
2. 在队头出队时,优先队列会返回堆顶元素并调整堆。
关于堆的具体实现可以看[](https://javaguide.cn/cs-basics/data-structure/heap.html)这一节。
总而言之,不论我们进行什么操作,优先队列都能按照**某种排序方式**进行一系列堆的相关操作,从而保证整个集合的**有序性**。
虽然优先队列的底层并非严格的线性结构,但是在我们使用的过程中,我们是感知不到**堆**的,从使用者的眼中优先队列可以被认为是一种线性的数据结构:一种会自动排序的线性队列。
### 4.3. 常见应用场景
当我们需要按照一定顺序来处理数据的时候可以考虑使用队列这个数据结构。
- **阻塞队列:** 阻塞队列可以看成在队列基础上加了阻塞操作的队列。当队列为空的时候,出队操作阻塞,当队列满的时候,入队操作阻塞。使用阻塞队列我们可以很容易实现“生产者 - 消费者“模型。
- **线程池中的请求/任务队列:** 线程池中没有空闲线程时,新的任务请求线程资源时,线程池该如何处理呢?答案是将这些请求放在队列中,当有空闲线程的时候,会循环中反复从队列中获取任务来执行。队列分为无界队列(基于链表)和有界队列(基于数组)。无界队列的特点就是可以一直入列,除非系统资源耗尽,比如:`FixedThreadPool` 使用无界队列 `LinkedBlockingQueue`。但是有界队列就不一样了,当队列满的话后面再有任务/请求就会拒绝,在 Java 中的体现就是会抛出`java.util.concurrent.RejectedExecutionException` 异常。
- 栈:双端队列天生便可以实现栈的全部功能(`push``pop``peek`并且在Deque接口中已经实现了相关方法。Stack 类已经和 Vector 一样被遗弃,现在在 Java 中普遍使用双端队列Deque来实现栈。
- Linux 内核进程队列(按优先级排队)
- 现实生活中的派对,播放器上的播放列表;
- 消息队列

View File

@ -953,10 +953,9 @@ WHERE condition;
```sql
SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
WHERE order_num IN (SELECT DISTINCT order_num
FROM OrderItems
GROUP BY order_num
HAVING Sum(item_price) >= 10)
where item_price >= 10)
```
### 确定哪些订单购买了 prod_id 为 BR01 的产品(一)

View File

@ -118,6 +118,7 @@ LRUCache < Integer, String > cache = new LRUCache < > (2);
cache.put(1, "one");
cache.put(2, "two");
cache.put(3, "three");
cache.put(4, "four");
for (int i = 0; i < 4; i++) {
System.out.println(cache.get(i));
}
@ -129,6 +130,7 @@ for (int i = 0; i < 4; i++) {
null
null
three
four
```
从输出结果来看,由于缓存容量为 2 ,因此,添加第 3 个元素时,第 1 个元素会被删除。添加第 4 个元素时,第 2 个元素会被删除。
@ -139,7 +141,7 @@ three
在正式讨论 `LinkedHashMap` 前,我们先来聊聊 `LinkedHashMap` 节点 `Entry` 的设计,我们都知道 `HashMap` 的 bucket 上的因为冲突转为链表的节点会在符合以下两个条件时会将链表转为红黑树:
1. 链表上的节点个数达到树化的阈值-1,即`TREEIFY_THRESHOLD - 1`
1. 链表上的节点个数达到树化的阈值7,即`TREEIFY_THRESHOLD - 1`
2. bucket 的容量达到最小的树化容量即`MIN_TREEIFY_CAPACITY`
`LinkedHashMap` 是在 `HashMap` 的基础上为 bucket 上的每一个节点建立一条双向链表,这就使得转为红黑树的树节点也需要具备双向链表节点的特性,即每一个树节点都需要拥有两个引用存储前驱节点和后继节点的地址,所以对于树节点类 `TreeNode` 的设计就是一个比较棘手的问题。

View File

@ -76,7 +76,7 @@ Java 14([ JEP 370](https://openjdk.org/jeps/370)) 的时候,第一次孵化外
- 通用:单个 API 应该能够对各种外部内存(如本机内存、持久内存、堆内存等)进行操作。
- 安全无论操作何种内存API 都不应该破坏 JVM 的安全性。
- 控制:可以自由的选择如何释放内存(显式、隐式等)。
- 可用如果需要访问外部内存API 应该是 `sun.misc.Unsafa`.
- 可用如果需要访问外部内存API 应该是 `sun.misc.Unsafe`.
## JEP 394:instanceof 模式匹配(转正)