Skip to content

Commit 3f4ec97

Browse files
authored
🎨
1 parent f6b9439 commit 3f4ec97

File tree

1 file changed

+32
-28
lines changed

1 file changed

+32
-28
lines changed

ch16/01_Using_the_Methods_of_Map.md

+32-28
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,74 @@
33

44
### 使用Map的方法
55

6-
正如我们在前两章中所做的那样,将待办事项管理器置于优先级队列中的一个问题是优先级队列无法保留将元素添加到它们的顺序(除非可以按优先级顺序 例如作为时间戳或序列号)。 为了避免这种情况,我们可以使用一系列 `FIFO 队列作为替代模型,每个队列分配一个优先级。 一个 `Map` 适合于保持优先级与任务队列之间的关联; 特别是 `EnumMap` 是一个高效的 `Map` 实现,专门用于与枚举成员关键字一起使用。
6+
正如我们在前两章中所做的那样,将待办事项管理器置于优先级队列中的一个问题是优先级队列无法保留将元素添加到它们的顺序(除非可以按优先级顺序 例如作为时间
7+
戳或序列号)。 为了避免这种情况,我们可以使用一系列 `FIFO` 队列作为替代模型,每个队列分配一个优先级。 一个 `Map` 适合于保持优先级与任务队列之间的关
8+
联; 特别是 `EnumMap` 是一个高效的 `Map` 实现,专门用于与枚举成员关键字一起使用。
79

810
该模型将依赖于保持 `FIFO` 排序的队列实现。 为了关注 `Map` 方法的使用,我们假设一个单线程客户端并使用一系列 `ArrayDeques` 作为实现:
911

1012
```java
11-
Map<Priority,ArrayDeque<Task>> taskMap = new EnumMap<Priority,ArrayDeque<Task>>(Priority.class);
12-
for (Priority p : Priority.values()) {
13-
taskMap.put(p, new ArrayDeque<Task>());
14-
}
15-
// 填充列表,例如:
16-
taskMap.get(Priority.MEDIUM).add(mikePhone);
17-
taskMap.get(Priority.HIGH).add(databaseCode);
13+
Map<Priority,ArrayDeque<Task>> taskMap = new EnumMap<Priority,ArrayDeque<Task>>(Priority.class);
14+
for (Priority p : Priority.values()) {
15+
taskMap.put(p, new ArrayDeque<Task>());
16+
}
17+
// 填充列表,例如:
18+
taskMap.get(Priority.MEDIUM).add(mikePhone);
19+
taskMap.get(Priority.HIGH).add(databaseCode);
1820
```
1921

2022
现在,要进入任务队列之一 - 比如说具有最高优先级任务的队列 - 我们可以这样写:
2123

2224
```java
23-
Queue<Task> highPriorityTaskList = taskMap.get(Priority.HIGH);
25+
Queue<Task> highPriorityTaskList = taskMap.get(Priority.HIGH);
2426
```
2527

2628
轮询此队列现在将按照它们进入系统的顺序为我们提供高优先级待办事项。
2729

28-
为了看到其他一些 `Map` 方法的使用,让我们稍微扩展一下这个例子,以允许这些任务中的一些实际上可以通过计费赚取一些钱。 表示这种方法的一种方法是定义一个类 `Client`
30+
为了看到其他一些 `Map` 方法的使用,让我们稍微扩展一下这个例子,以允许这些任务中的一些实际上可以通过计费赚取一些钱。 表示这种方法的一种方法是定义一个
31+
`Client`
2932

3033
```java
31-
class Client {...}
32-
Client acme = new Client("Acme Corp.",...);
34+
class Client {...}
35+
Client acme = new Client("Acme Corp.",...);
3336
```
3437

3538
并创建从任务到客户的映射:
3639

3740
```java
38-
Map<Task,Client> billingMap = new HashMap<Task,Client>();
39-
billingMap.put(interfaceCode, acme);
41+
Map<Task,Client> billingMap = new HashMap<Task,Client>();
42+
billingMap.put(interfaceCode, acme);
4043
```
4144

42-
我们需要确保系统仍然可以处理无法填写的任务。我们在这里有一个选择:我们可以简单地将不可填写任务的名称添加到 `billingMap` 中,也可以将其映射为 `null`。无论哪种情况,作为处理任务 `t` 的代码的一部分,我们可以写出:
45+
我们需要确保系统仍然可以处理无法填写的任务。我们在这里有一个选择:我们可以简单地将不可填写任务的名称添加到 `billingMap` 中,也可以将其映射为
46+
`null`。无论哪种情况,作为处理任务 `t` 的代码的一部分,我们可以写出:
4347

4448
```java
45-
Task t = ...
46-
Client client = billingMap.get(t);
47-
if (client != null) {
48-
client.bill(t);
49-
}
49+
Task t = ...
50+
Client client = billingMap.get(t);
51+
if (client != null) {
52+
client.bill(t);
53+
}
5054
```
5155

5256
当我们终于完成了我们的客户 `Acme Corp`.承包的所有工作时,可以删除将任务与 `Acme` 关联的 `Map` 条目:
5357

5458
```java
55-
Collection<Client> clients = billingMap.values();
56-
for (Iterator<Client> iter = clients.iterator() ; iter.hasNext() ; ) {
57-
if (iter.next().equals(acme)) {
58-
iter.remove();
59-
}
60-
}
59+
Collection<Client> clients = billingMap.values();
60+
for (Iterator<Client> iter = clients.iterator() ; iter.hasNext() ; ) {
61+
if (iter.next().equals(acme)) {
62+
iter.remove();
63+
}
64+
}
6165
```
6266

6367
整洁的替代方法利用方法 `Collections.singleton`(参见 `17.2` 节),该方法返回一个只包含指定元素的不可变 `Set`
6468

6569
```java
66-
clients.removeAll(Collections.singleton(acme));
70+
clients.removeAll(Collections.singleton(acme));
6771
```
6872

6973
这两种方法的成本都是 `O(n)``Sun` 在当前的实施中具有类似的常数因子。
7074

7175
《《《 [下一节](02_Implementing_Map.md) <br/>
72-
《《《 [返回首页](../README.md)
76+
《《《 [返回首页](../README.md)

0 commit comments

Comments
 (0)