auto commit
This commit is contained in:
parent
0012f2a913
commit
3774c158f6
@ -126,7 +126,7 @@ public class ArrayList<E> extends AbstractList<E>
|
|||||||
private static final int DEFAULT_CAPACITY = 10;
|
private static final int DEFAULT_CAPACITY = 10;
|
||||||
```
|
```
|
||||||
|
|
||||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/52a7744f-5bce-4ff3-a6f0-8449334d9f3d.png" width="400px"> </div><br>
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208232221265.png"/> </div><br>
|
||||||
|
|
||||||
### 2. 扩容
|
### 2. 扩容
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ private void grow(int minCapacity) {
|
|||||||
|
|
||||||
### 3. 删除元素
|
### 3. 删除元素
|
||||||
|
|
||||||
需要调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,该操作的时间复杂度为 O(N),可以看出 ArrayList 删除元素的代价是非常高的。
|
需要调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,该操作的时间复杂度为 O(N),可以看到 ArrayList 删除元素的代价是非常高的。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public E remove(int index) {
|
public E remove(int index) {
|
||||||
@ -185,34 +185,7 @@ public E remove(int index) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Fail-Fast
|
### 4. 序列化
|
||||||
|
|
||||||
modCount 用来记录 ArrayList 结构发生变化的次数。结构发生变化是指添加或者删除至少一个元素的所有操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化。
|
|
||||||
|
|
||||||
在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了需要抛出 ConcurrentModificationException。
|
|
||||||
|
|
||||||
```java
|
|
||||||
private void writeObject(java.io.ObjectOutputStream s)
|
|
||||||
throws java.io.IOException{
|
|
||||||
// Write out element count, and any hidden stuff
|
|
||||||
int expectedModCount = modCount;
|
|
||||||
s.defaultWriteObject();
|
|
||||||
|
|
||||||
// Write out size as capacity for behavioural compatibility with clone()
|
|
||||||
s.writeInt(size);
|
|
||||||
|
|
||||||
// Write out all elements in the proper order.
|
|
||||||
for (int i=0; i<size; i++) {
|
|
||||||
s.writeObject(elementData[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modCount != expectedModCount) {
|
|
||||||
throw new ConcurrentModificationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. 序列化
|
|
||||||
|
|
||||||
ArrayList 基于数组实现,并且具有动态扩容特性,因此保存元素的数组不一定都会被使用,那么就没必要全部进行序列化。
|
ArrayList 基于数组实现,并且具有动态扩容特性,因此保存元素的数组不一定都会被使用,那么就没必要全部进行序列化。
|
||||||
|
|
||||||
@ -277,6 +250,13 @@ ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
|
|||||||
oos.writeObject(list);
|
oos.writeObject(list);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 5. Fail-Fast
|
||||||
|
|
||||||
|
modCount 用来记录 ArrayList 结构发生变化的次数。结构发生变化是指添加或者删除至少一个元素的所有操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化。
|
||||||
|
|
||||||
|
在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了需要抛出 ConcurrentModificationException。代码参考上节序列化中的 writeObject() 方法。
|
||||||
|
|
||||||
|
|
||||||
## Vector
|
## Vector
|
||||||
|
|
||||||
### 1. 同步
|
### 1. 同步
|
||||||
@ -362,7 +342,7 @@ List<String> list = new CopyOnWriteArrayList<>();
|
|||||||
|
|
||||||
## CopyOnWriteArrayList
|
## CopyOnWriteArrayList
|
||||||
|
|
||||||
### 读写分离
|
### 1. 读写分离
|
||||||
|
|
||||||
写操作在一个复制的数组上进行,读操作还是在原始数组中进行,读写分离,互不影响。
|
写操作在一个复制的数组上进行,读操作还是在原始数组中进行,读写分离,互不影响。
|
||||||
|
|
||||||
@ -398,7 +378,7 @@ private E get(Object[] a, int index) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 适用场景
|
### 2. 适用场景
|
||||||
|
|
||||||
CopyOnWriteArrayList 在写操作的同时允许读操作,大大提高了读操作的性能,因此很适合读多写少的应用场景。
|
CopyOnWriteArrayList 在写操作的同时允许读操作,大大提高了读操作的性能,因此很适合读多写少的应用场景。
|
||||||
|
|
||||||
@ -430,13 +410,14 @@ transient Node<E> first;
|
|||||||
transient Node<E> last;
|
transient Node<E> last;
|
||||||
```
|
```
|
||||||
|
|
||||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c8563120-cb00-4dd6-9213-9d9b337a7f7c.png" width="500px"> </div><br>
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208233940066.png"/> </div><br>
|
||||||
|
|
||||||
### 2. 与 ArrayList 的比较
|
### 2. 与 ArrayList 的比较
|
||||||
|
|
||||||
- ArrayList 基于动态数组实现,LinkedList 基于双向链表实现;
|
ArrayList 基于动态数组实现,LinkedList 基于双向链表实现。ArrayList 和 LinkedList 的区别可以归结为数组和链表的区别:
|
||||||
- ArrayList 支持随机访问,LinkedList 不支持;
|
|
||||||
- LinkedList 在任意位置添加删除元素更快。
|
- 数组支持随机访问,但插入删除的代价很高,需要移动大量元素;
|
||||||
|
- 链表不支持随机访问,但插入删除只需要改变指针。
|
||||||
|
|
||||||
## HashMap
|
## HashMap
|
||||||
|
|
||||||
@ -444,16 +425,14 @@ transient Node<E> last;
|
|||||||
|
|
||||||
### 1. 存储结构
|
### 1. 存储结构
|
||||||
|
|
||||||
内部包含了一个 Entry 类型的数组 table。
|
内部包含了一个 Entry 类型的数组 table。Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值和散列桶取模运算结果相同的 Entry。
|
||||||
|
|
||||||
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208234948205.png"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
transient Entry[] table;
|
transient Entry[] table;
|
||||||
```
|
```
|
||||||
|
|
||||||
Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值和散列桶取模运算结果相同的 Entry。
|
|
||||||
|
|
||||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9420a703-1f9d-42ce-808e-bcb82b56483d.png" width="550px"> </div><br>
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
static class Entry<K,V> implements Map.Entry<K,V> {
|
static class Entry<K,V> implements Map.Entry<K,V> {
|
||||||
final K key;
|
final K key;
|
||||||
@ -528,7 +507,7 @@ map.put("K3", "V3");
|
|||||||
- 计算键值对所在的桶;
|
- 计算键值对所在的桶;
|
||||||
- 在链表上顺序查找,时间复杂度显然和链表的长度成正比。
|
- 在链表上顺序查找,时间复杂度显然和链表的长度成正比。
|
||||||
|
|
||||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e0870f80-b79e-4542-ae39-7420d4b0d8fe.png" width="550px"> </div><br>
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208235258643.png"/> </div><br>
|
||||||
|
|
||||||
### 3. put 操作
|
### 3. put 操作
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ public class ArrayList<E> extends AbstractList<E>
|
|||||||
private static final int DEFAULT_CAPACITY = 10;
|
private static final int DEFAULT_CAPACITY = 10;
|
||||||
```
|
```
|
||||||
|
|
||||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/52a7744f-5bce-4ff3-a6f0-8449334d9f3d.png" width="400px"> </div><br>
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208232221265.png"/> </div><br>
|
||||||
|
|
||||||
### 2. 扩容
|
### 2. 扩容
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ private void grow(int minCapacity) {
|
|||||||
|
|
||||||
### 3. 删除元素
|
### 3. 删除元素
|
||||||
|
|
||||||
需要调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,该操作的时间复杂度为 O(N),可以看出 ArrayList 删除元素的代价是非常高的。
|
需要调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,该操作的时间复杂度为 O(N),可以看到 ArrayList 删除元素的代价是非常高的。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public E remove(int index) {
|
public E remove(int index) {
|
||||||
@ -185,34 +185,7 @@ public E remove(int index) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Fail-Fast
|
### 4. 序列化
|
||||||
|
|
||||||
modCount 用来记录 ArrayList 结构发生变化的次数。结构发生变化是指添加或者删除至少一个元素的所有操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化。
|
|
||||||
|
|
||||||
在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了需要抛出 ConcurrentModificationException。
|
|
||||||
|
|
||||||
```java
|
|
||||||
private void writeObject(java.io.ObjectOutputStream s)
|
|
||||||
throws java.io.IOException{
|
|
||||||
// Write out element count, and any hidden stuff
|
|
||||||
int expectedModCount = modCount;
|
|
||||||
s.defaultWriteObject();
|
|
||||||
|
|
||||||
// Write out size as capacity for behavioural compatibility with clone()
|
|
||||||
s.writeInt(size);
|
|
||||||
|
|
||||||
// Write out all elements in the proper order.
|
|
||||||
for (int i=0; i<size; i++) {
|
|
||||||
s.writeObject(elementData[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modCount != expectedModCount) {
|
|
||||||
throw new ConcurrentModificationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. 序列化
|
|
||||||
|
|
||||||
ArrayList 基于数组实现,并且具有动态扩容特性,因此保存元素的数组不一定都会被使用,那么就没必要全部进行序列化。
|
ArrayList 基于数组实现,并且具有动态扩容特性,因此保存元素的数组不一定都会被使用,那么就没必要全部进行序列化。
|
||||||
|
|
||||||
@ -277,6 +250,13 @@ ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
|
|||||||
oos.writeObject(list);
|
oos.writeObject(list);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 5. Fail-Fast
|
||||||
|
|
||||||
|
modCount 用来记录 ArrayList 结构发生变化的次数。结构发生变化是指添加或者删除至少一个元素的所有操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化。
|
||||||
|
|
||||||
|
在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了需要抛出 ConcurrentModificationException。代码参考上节序列化中的 writeObject() 方法。
|
||||||
|
|
||||||
|
|
||||||
## Vector
|
## Vector
|
||||||
|
|
||||||
### 1. 同步
|
### 1. 同步
|
||||||
@ -362,7 +342,7 @@ List<String> list = new CopyOnWriteArrayList<>();
|
|||||||
|
|
||||||
## CopyOnWriteArrayList
|
## CopyOnWriteArrayList
|
||||||
|
|
||||||
### 读写分离
|
### 1. 读写分离
|
||||||
|
|
||||||
写操作在一个复制的数组上进行,读操作还是在原始数组中进行,读写分离,互不影响。
|
写操作在一个复制的数组上进行,读操作还是在原始数组中进行,读写分离,互不影响。
|
||||||
|
|
||||||
@ -398,7 +378,7 @@ private E get(Object[] a, int index) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 适用场景
|
### 2. 适用场景
|
||||||
|
|
||||||
CopyOnWriteArrayList 在写操作的同时允许读操作,大大提高了读操作的性能,因此很适合读多写少的应用场景。
|
CopyOnWriteArrayList 在写操作的同时允许读操作,大大提高了读操作的性能,因此很适合读多写少的应用场景。
|
||||||
|
|
||||||
@ -430,13 +410,14 @@ transient Node<E> first;
|
|||||||
transient Node<E> last;
|
transient Node<E> last;
|
||||||
```
|
```
|
||||||
|
|
||||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c8563120-cb00-4dd6-9213-9d9b337a7f7c.png" width="500px"> </div><br>
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208233940066.png"/> </div><br>
|
||||||
|
|
||||||
### 2. 与 ArrayList 的比较
|
### 2. 与 ArrayList 的比较
|
||||||
|
|
||||||
- ArrayList 基于动态数组实现,LinkedList 基于双向链表实现;
|
ArrayList 基于动态数组实现,LinkedList 基于双向链表实现。ArrayList 和 LinkedList 的区别可以归结为数组和链表的区别:
|
||||||
- ArrayList 支持随机访问,LinkedList 不支持;
|
|
||||||
- LinkedList 在任意位置添加删除元素更快。
|
- 数组支持随机访问,但插入删除的代价很高,需要移动大量元素;
|
||||||
|
- 链表不支持随机访问,但插入删除只需要改变指针。
|
||||||
|
|
||||||
## HashMap
|
## HashMap
|
||||||
|
|
||||||
@ -444,16 +425,14 @@ transient Node<E> last;
|
|||||||
|
|
||||||
### 1. 存储结构
|
### 1. 存储结构
|
||||||
|
|
||||||
内部包含了一个 Entry 类型的数组 table。
|
内部包含了一个 Entry 类型的数组 table。Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值和散列桶取模运算结果相同的 Entry。
|
||||||
|
|
||||||
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208234948205.png"/> </div><br>
|
||||||
|
|
||||||
```java
|
```java
|
||||||
transient Entry[] table;
|
transient Entry[] table;
|
||||||
```
|
```
|
||||||
|
|
||||||
Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值和散列桶取模运算结果相同的 Entry。
|
|
||||||
|
|
||||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9420a703-1f9d-42ce-808e-bcb82b56483d.png" width="550px"> </div><br>
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
static class Entry<K,V> implements Map.Entry<K,V> {
|
static class Entry<K,V> implements Map.Entry<K,V> {
|
||||||
final K key;
|
final K key;
|
||||||
@ -528,7 +507,7 @@ map.put("K3", "V3");
|
|||||||
- 计算键值对所在的桶;
|
- 计算键值对所在的桶;
|
||||||
- 在链表上顺序查找,时间复杂度显然和链表的长度成正比。
|
- 在链表上顺序查找,时间复杂度显然和链表的长度成正比。
|
||||||
|
|
||||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e0870f80-b79e-4542-ae39-7420d4b0d8fe.png" width="550px"> </div><br>
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208235258643.png"/> </div><br>
|
||||||
|
|
||||||
### 3. put 操作
|
### 3. put 操作
|
||||||
|
|
||||||
|
BIN
notes/pics/image-20191208232221265.png
Normal file
BIN
notes/pics/image-20191208232221265.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
notes/pics/image-20191208233940066.png
Normal file
BIN
notes/pics/image-20191208233940066.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
notes/pics/image-20191208234825587.png
Normal file
BIN
notes/pics/image-20191208234825587.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
BIN
notes/pics/image-20191208234948205.png
Normal file
BIN
notes/pics/image-20191208234948205.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
BIN
notes/pics/image-20191208235258643.png
Normal file
BIN
notes/pics/image-20191208235258643.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
Loading…
Reference in New Issue
Block a user