auto commit

This commit is contained in:
CyC2018 2019-12-08 23:53:16 +08:00
parent 0012f2a913
commit 3774c158f6
7 changed files with 42 additions and 84 deletions

View File

@ -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 类型的数组 tableEntry 存储着键值对它包含了四个字段 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 操作

View File

@ -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 类型的数组 tableEntry 存储着键值对它包含了四个字段 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 操作

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB