From ddb9e86224f11781f3befca6eb30aa5ef276abb5 Mon Sep 17 00:00:00 2001
From: CyC2018 <1029579233@qq.com>
Date: Mon, 13 Aug 2018 20:44:07 +0800
Subject: [PATCH] auto commit
---
notes/Java 容器.md | 48 +++++++++++++++++++++++++---------------------
1 file changed, 26 insertions(+), 22 deletions(-)
diff --git a/notes/Java 容器.md b/notes/Java 容器.md
index 4ae57b25..9959e2ca 100644
--- a/notes/Java 容器.md
+++ b/notes/Java 容器.md
@@ -21,7 +21,7 @@
# 一、概览
-容器主要包括 Collection 和 Map 两种,Collection 又包含了 List、Set 以及 Queue。
+容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表。
## Collection
@@ -29,9 +29,9 @@
### 1. Set
-- HashSet:基于哈希表实现,支持快速查找。但不支持有序性操作,例如根据一个范围查找元素的操作。并且失去了元素的插入顺序信息,也就是说使用 Iterator 遍历 HashSet 得到的结果是不确定的。
+- TreeSet:基于红黑树实现,支持有序性操作,例如根据一个范围查找元素的操作。但是查找效率不如 HashSet,HashSet 查找的时间复杂度为 O(1),TreeSet 则为 O(logN)。
-- TreeSet:基于红黑树实现,支持有序性操作,但是查找效率不如 HashSet,HashSet 查找时间复杂度为 O(1),TreeSet 则为 O(logN)。
+- HashSet:基于哈希表实现,支持快速查找,但不支持有序性操作。并且失去了元素的插入顺序信息,也就是说使用 Iterator 遍历 HashSet 得到的结果是不确定的。
- LinkedHashSet:具有 HashSet 的查找效率,且内部使用双向链表维护元素的插入顺序。
@@ -53,13 +53,14 @@
-- HashMap:基于哈希表实现;
+- TreeMap:基于红黑树实现。
+
+- HashMap:基于哈希表实现。
- HashTable:和 HashMap 类似,但它是线程安全的,这意味着同一时刻多个线程可以同时写入 HashTable 并且不会导致数据不一致。它是遗留类,不应该去使用它。现在可以使用 ConcurrentHashMap 来支持线程安全,并且 ConcurrentHashMap 的效率会更高,因为 ConcurrentHashMap 引入了分段锁。
- LinkedHashMap:使用双向链表来维护元素的顺序,顺序为插入顺序或者最近最少使用(LRU)顺序。
-- TreeMap:基于红黑树实现。
# 二、容器中的设计模式
@@ -296,14 +297,14 @@ public synchronized E get(int index) {
}
```
-### 2. 与 ArrayList 的区别
+### 2. 与 ArrayList 的比较
- Vector 是同步的,因此开销就比 ArrayList 要大,访问速度更慢。最好使用 ArrayList 而不是 Vector,因为同步操作完全可以由程序员自己来控制;
- Vector 每次扩容请求其大小的 2 倍空间,而 ArrayList 是 1.5 倍。
### 3. 替代方案
-为了获得线程安全的 ArrayList,可以使用 `Collections.synchronizedList();` 得到一个线程安全的 ArrayList。
+可以使用 `Collections.synchronizedList();` 得到一个线程安全的 ArrayList。
```java
List list = new ArrayList<>();
@@ -322,7 +323,7 @@ List list = new CopyOnWriteArrayList<>();
写操作在一个复制的数组上进行,读操作还是在原始数组中进行,读写分离,互不影响。
-写操作需要加锁,防止同时并发写入时导致的写入数据丢失。
+写操作需要加锁,防止并发写入时导致写入数据丢失。
写操作结束之后需要把原始数组指向新的复制数组。
@@ -386,9 +387,9 @@ transient Node first;
transient Node last;
```
-
+
-### 2. ArrayList 与 LinkedList
+### 2. 与 ArrayList 的比较
- ArrayList 基于动态数组实现,LinkedList 基于双向链表实现;
- ArrayList 支持随机访问,LinkedList 不支持;
@@ -406,7 +407,7 @@ transient Node last;
transient Entry[] table;
```
-其中,Entry 就是存储数据的键值对,它包含了四个字段。从 next 字段我们可以看出 Entry 是一个链表,即数组中的每个位置被当成一个桶,一个桶存放一个链表,链表中存放哈希值相同的 Entry。也就是说,HashMap 使用拉链法来解决冲突。
+Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值相同的 Entry。
@@ -634,8 +635,8 @@ y&(x-1) : 00000010
这个性质和 y 对 x 取模效果是一样的:
```
-x : 00010000
y : 10110010
+x : 00010000
y%x : 00000010
```
@@ -693,7 +694,7 @@ void addEntry(int hash, K key, V value, int bucketIndex) {
}
```
-扩容使用 resize() 实现,需要注意的是,扩容操作同样需要把旧 table 的所有键值对重新插入新的 table 中,因此这一步是很费时的。
+扩容使用 resize() 实现,需要注意的是,扩容操作同样需要把 oldTable 的所有键值对重新插入 newTable 中,因此这一步是很费时的。
```java
void resize(int newCapacity) {
@@ -739,7 +740,10 @@ capacity : 00010000
new capacity : 00100000
```
-对于一个 Key,它的哈希值如果在第 6 位上为 0,那么取模得到的结果和之前一样;如果为 1,那么得到的结果为原来的结果 +16。
+对于一个 Key,
+
+- 它的哈希值如果在第 6 位上为 0,那么取模得到的结果和之前一样;
+- 如果为 1,那么得到的结果为原来的结果 +16。
### 7. 扩容-计算数组容量
@@ -778,7 +782,7 @@ static final int tableSizeFor(int cap) {
从 JDK 1.8 开始,一个桶存储的链表长度大于 8 时会将链表转换为红黑树。
-### 9. HashMap 与 HashTable
+### 9. 与 HashTable 的比较
- HashTable 使用 synchronized 来进行同步。
- HashMap 可以插入键为 null 的 Entry。
@@ -939,7 +943,7 @@ transient LinkedHashMap.Entry head;
transient LinkedHashMap.Entry tail;
```
-accessOrder 决定了顺序,默认为 false,此时使用的是插入顺序。
+accessOrder 决定了顺序,默认为 false,此时维护的是插入顺序。
```java
final boolean accessOrder;
@@ -954,7 +958,7 @@ void afterNodeInsertion(boolean evict) { }
### afterNodeAccess()
-当一个节点被访问时,如果 accessOrder 为 true,则会将 该节点移到链表尾部。也就是说指定为 LRU 顺序之后,在每次访问一个节点时,会将这个节点移到链表尾部,保证链表尾部是最近访问的节点,那么链表首部就是最近最久未使用的节点。
+当一个节点被访问时,如果 accessOrder 为 true,则会将该节点移到链表尾部。也就是说指定为 LRU 顺序之后,在每次访问一个节点时,会将这个节点移到链表尾部,保证链表尾部是最近访问的节点,那么链表首部就是最近最久未使用的节点。
```java
void afterNodeAccess(Node e) { // move node to last
@@ -1003,8 +1007,8 @@ removeEldestEntry() 默认为 false,如果需要让它为 true,需要继承
```java
protected boolean removeEldestEntry(Map.Entry eldest) {
- return false;
- }
+ return false;
+}
```
### LRU 缓存
@@ -1059,14 +1063,14 @@ private static class Entry extends WeakReference