@@ -126,7 +126,7 @@ public class ArrayList<E> extends AbstractList<E>
126126private static final int DEFAULT_CAPACITY = 10;
127127```
128128
129- <div align="center"> <img src="https:// cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/52a7744f-5bce-4ff3-a6f0-8449334d9f3d .png" width="400px" > </div><br>
129+ <div align="center"> <img src="https:// cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208232221265 .png"/ > </div><br>
130130
131131### 2. 扩容
132132
@@ -170,7 +170,7 @@ private void grow(int minCapacity) {
170170
171171### 3. 删除元素
172172
173- 需要调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,该操作的时间复杂度为 O(N),可以看出 ArrayList 删除元素的代价是非常高的。
173+ 需要调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,该操作的时间复杂度为 O(N),可以看到 ArrayList 删除元素的代价是非常高的。
174174
175175``` java
176176public E remove(int index) {
@@ -185,34 +185,7 @@ public E remove(int index) {
185185}
186186```
187187
188- ### 4. Fail-Fast
189-
190- modCount 用来记录 ArrayList 结构发生变化的次数。结构发生变化是指添加或者删除至少一个元素的所有操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化。
191-
192- 在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了需要抛出 ConcurrentModificationException。
193-
194- ``` java
195- private void writeObject(java.io. ObjectOutputStream s)
196- throws java.io. IOException {
197- // Write out element count, and any hidden stuff
198- int expectedModCount = modCount;
199- s. defaultWriteObject();
200-
201- // Write out size as capacity for behavioural compatibility with clone()
202- s. writeInt(size);
203-
204- // Write out all elements in the proper order.
205- for (int i= 0 ; i< size; i++ ) {
206- s. writeObject(elementData[i]);
207- }
208-
209- if (modCount != expectedModCount) {
210- throw new ConcurrentModificationException ();
211- }
212- }
213- ```
214-
215- ### 5. 序列化
188+ ### 4. 序列化
216189
217190ArrayList 基于数组实现,并且具有动态扩容特性,因此保存元素的数组不一定都会被使用,那么就没必要全部进行序列化。
218191
@@ -277,6 +250,13 @@ ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
277250oos. writeObject(list);
278251```
279252
253+ ### 5. Fail-Fast
254+
255+ modCount 用来记录 ArrayList 结构发生变化的次数。结构发生变化是指添加或者删除至少一个元素的所有操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化。
256+
257+ 在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了需要抛出 ConcurrentModificationException。代码参考上节序列化中的 writeObject() 方法。
258+
259+
280260## Vector
281261
282262### 1. 同步
@@ -362,7 +342,7 @@ List<String> list = new CopyOnWriteArrayList<>();
362342
363343## CopyOnWriteArrayList
364344
365- ### 读写分离
345+ ### 1. 读写分离
366346
367347写操作在一个复制的数组上进行,读操作还是在原始数组中进行,读写分离,互不影响。
368348
@@ -398,7 +378,7 @@ private E get(Object[] a, int index) {
398378}
399379```
400380
401- ### 适用场景
381+ ### 2. 适用场景
402382
403383CopyOnWriteArrayList 在写操作的同时允许读操作,大大提高了读操作的性能,因此很适合读多写少的应用场景。
404384
@@ -430,30 +410,29 @@ transient Node<E> first;
430410transient Node<E > last;
431411```
432412
433- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c8563120-cb00-4dd6-9213-9d9b337a7f7c .png " width = " 500px " > </div ><br >
413+ <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208233940066 .png " / > </div ><br >
434414
435415### 2. 与 ArrayList 的比较
436416
437- - ArrayList 基于动态数组实现,LinkedList 基于双向链表实现;
438- - ArrayList 支持随机访问,LinkedList 不支持;
439- - LinkedList 在任意位置添加删除元素更快。
417+ ArrayList 基于动态数组实现,LinkedList 基于双向链表实现。ArrayList 和 LinkedList 的区别可以归结为数组和链表的区别:
418+
419+ - 数组支持随机访问,但插入删除的代价很高,需要移动大量元素;
420+ - 链表不支持随机访问,但插入删除只需要改变指针。
440421
441422## HashMap
442423
443424为了便于理解,以下源码分析以 JDK 1.7 为主。
444425
445426### 1. 存储结构
446427
447- 内部包含了一个 Entry 类型的数组 table。
428+ 内部包含了一个 Entry 类型的数组 table。Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值和散列桶取模运算结果相同的 Entry。
429+
430+ <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208234948205.png " /> </div ><br >
448431
449432``` java
450433transient Entry [] table;
451434```
452435
453- Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值和散列桶取模运算结果相同的 Entry。
454-
455- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9420a703-1f9d-42ce-808e-bcb82b56483d.png " width =" 550px " > </div ><br >
456-
457436``` java
458437static class Entry <K,V> implements Map .Entry<K ,V > {
459438 final K key;
@@ -528,7 +507,7 @@ map.put("K3", "V3");
528507- 计算键值对所在的桶;
529508- 在链表上顺序查找,时间复杂度显然和链表的长度成正比。
530509
531- <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e0870f80-b79e-4542-ae39-7420d4b0d8fe .png " width = " 550px " > </div ><br >
510+ <div align =" center " > <img src =" https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208235258643 .png " / > </div ><br >
532511
533512### 3. put 操作
534513
0 commit comments