Skip to content

Commit 0bb45d9

Browse files
author
DeleiGuo
committed
update
1 parent 2d06d0c commit 0bb45d9

File tree

5 files changed

+625
-108
lines changed

5 files changed

+625
-108
lines changed

doc/jdk/src/java/lang/Object.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Object
22

3-
> 非特殊说明时,源码均基于AdoptOpenJDK
3+
> 非特殊说明时,源码均基于AdoptOpenJDK11
44
>
55
> 作者: DeleiGuo
66
> 版权: 本文非特别声明外,均采用 © CC-BY-NC-SA 4.0 许可协议

doc/jdk/src/java/lang/String.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# String
22

3-
> 非特殊说明时,源码均基于AdoptOpenJDK
3+
> 非特殊说明时,源码均基于AdoptOpenJDK11
44
>
55
> 作者: DeleiGuo
66
> 版权: 本文非特别声明外,均采用 © CC-BY-NC-SA 4.0 许可协议

doc/jdk/src/java/lang/StringBuilder与StringBuffer.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# StringBuilder与StringBuffer
22

3-
> 非特殊说明时,源码均基于AdoptOpenJDK
3+
> 非特殊说明时,源码均基于AdoptOpenJDK11
44
>
55
> 作者: DeleiGuo
66
> 版权: 本文非特别声明外,均采用 © CC-BY-NC-SA 4.0 许可协议

doc/jdk/src/java/util/ArrayList.md

Lines changed: 197 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,235 @@
1+
# java.util.ArrayList
12

2-
#### java.util.ArrayList
3+
> 非特殊说明时,源码均基于AdoptOpenJDK11
4+
>
5+
> 作者: DeleiGuo
6+
> 版权: 本文非特别声明外,均采用 © CC-BY-NC-SA 4.0 许可协议
37
4-
* 基于数组方式实现,无容量限制;
5-
* 插入元素可能要扩容,删除元素并不会减少数组容量(如希望相应的缩小数组容量,可以调用ArrayList的trinToSize()),在查找元素时要遍历数组,对于非null得元素采取equals的方式寻找;
6-
* ArrayList是非线程安全的;
8+
## 1. 结构
79

8-
######ArrayList:数组方式存放对象
9-
创建ArrayList(int initialCapacity)
10+
```java
11+
public class ArrayList<E> extends AbstractList<E>
12+
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
1013
```
14+
15+
## 2. 属性
16+
17+
```java
1118
/**
12-
* Constructs an empty list with the specified initial capacity.
13-
*
14-
* @param initialCapacity the initial capacity of the list
15-
* @throws IllegalArgumentException if the specified initial capacity
16-
* is negative
19+
* Default initial capacity.
20+
* 默认容量大小为10
1721
*/
18-
public ArrayList(int ç) {
19-
super();
20-
if (initialCapacity < 0)
21-
throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
22-
this.elementData = new Object[initialCapacity];
23-
}
22+
private static final int DEFAULT_CAPACITY = 10;
23+
24+
/**
25+
* Shared empty array instance used for empty instances.
26+
* new ArrayList()无参构建函数时,大小为0
27+
* 第一次add() 时初始化 elementData 为DEFAULT_CAPACITY
28+
*/
29+
private static final Object[] EMPTY_ELEMENTDATA = {};
30+
31+
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
32+
33+
/**
34+
* 存储元素的对象数组
35+
* transient修饰
36+
*/
37+
transient Object[] elementData;
38+
39+
/**
40+
* 实际存储的元素数量
41+
*/
42+
private int size;
43+
44+
/** 最大的容量 */
45+
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
46+
47+
/** ===== 父类AbstractList中的重要属性 ===== */
48+
/** 修改次数,与 fast-fail 相关 */
49+
protected transient int modCount = 0;
2450
```
25-
其中,super方法调用的是AbstractList,在该类中此方法是个protected的空方法;所以,ArrayList的该方法主要是初始化了一个Object的数组,数组大小即为传入的initialCapacity。
2651

27-
######插入对象:add()
28-
源码:
52+
## 3. 主要方法
53+
54+
### 构造
55+
56+
``` java
57+
/** 无参构造函数 */
58+
public ArrayList() {
59+
// 默认元素数据为空的对象数组
60+
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
61+
}
62+
63+
/** 指定初始容量的有参构造函数 */
64+
public ArrayList(int initialCapacity) {
65+
// 判断容量参数并初始化数组
66+
if (initialCapacity > 0) {
67+
this.elementData = new Object[initialCapacity];
68+
} else if (initialCapacity == 0) {
69+
this.elementData = EMPTY_ELEMENTDATA;
70+
} else {
71+
throw new IllegalArgumentException("Illegal Capacity: "+
72+
initialCapacity);
73+
}
74+
}
2975
```
76+
77+
### 操作
78+
79+
```java
80+
/** 添加元素 */
3081
public boolean add(E e) {
31-
ensureCapacityInternal(size + 1); // Increments modCount!!
32-
elementData[size++] = e;
33-
return true;
82+
modCount++; // 此属性定义于父类AbstractList中
83+
add(e, elementData, size);
84+
return true;
3485
}
3586

36-
private void ensureCapacityInternal(int minCapacity) {
37-
if (elementData == EMPTY_ELEMENTDATA) {
38-
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
39-
}
40-
ensureExplicitCapacity(minCapacity);
87+
private void add(E e, Object[] elementData, int s) {
88+
if (s == elementData.length)
89+
elementData = grow(); // 扩容判断
90+
elementData[s] = e; // 将元素放入数组相应位置
91+
size = s + 1; // size+1
4192
}
4293

43-
private void ensureExplicitCapacity(int minCapacity) {
44-
modCount++;
45-
46-
// overflow-conscious code
47-
if (minCapacity - elementData.length > 0)
48-
grow(minCapacity);
94+
public void add(int index, E element) {
95+
rangeCheckForAdd(index); // 数组下标越界检查
96+
modCount++;
97+
final int s;
98+
Object[] elementData;
99+
if ((s = size) == (elementData = this.elementData).length)
100+
elementData = grow();
101+
// 复制数组/移动
102+
System.arraycopy(elementData, index,
103+
elementData, index + 1,
104+
s - index);
105+
elementData[index] = element;
106+
size = s + 1;
49107
}
50108

51-
private void grow(int minCapacity) {
52-
// overflow-conscious code
53-
int oldCapacity = elementData.length;
54-
int newCapacity = oldCapacity + (oldCapacity >> 1);
55-
if (newCapacity - minCapacity < 0)
56-
newCapacity = minCapacity;
57-
if (newCapacity - MAX_ARRAY_SIZE > 0)
58-
newCapacity = hugeCapacity(minCapacity);
59-
// minCapacity is usually close to size, so this is a win:
60-
elementData = Arrays.copyOf(elementData, newCapacity);
109+
public E remove(int index) {
110+
Objects.checkIndex(index, size); // 数组下标越界检车
111+
final Object[] es = elementData;
112+
113+
@SuppressWarnings("unchecked") E oldValue = (E) es[index];
114+
fastRemove(es, index);
115+
116+
return oldValue;
61117
}
62118

119+
private void fastRemove(Object[] es, int i) {
120+
modCount++;
121+
final int newSize;
122+
if ((newSize = size - 1) > i)
123+
// 数组复制/移动
124+
System.arraycopy(es, i + 1, es, i, newSize - i);
125+
es[size = newSize] = null; // 将结尾的元素置为 null
126+
}
63127
```
64128

65-
基于ArrayList中已有的元素数量+1到minCapacity,与elementData数组大小进行比较,如果大于当前elementData数组,则把当前elementData赋予给一个新的数组对象,其中通过计算当前数组值*1.5+1得出新的数组的容量,调用Arrays.copeOf方法来生成新的数组对象;
129+
### 扩容
66130

131+
```java
67132

68-
######删除对象:remove()
69-
源码:
70-
```
71-
public boolean remove(Object o) {
72-
if (o == null) {
73-
for (int index = 0; index < size; index++)
74-
if (elementData[index] == null) {
75-
fastRemove(index);
76-
return true;
77-
}
78-
} else {
79-
for (int index = 0; index < size; index++)
80-
if (o.equals(elementData[index])) {
81-
fastRemove(index);
82-
return true;
83-
}
84-
}
85-
return false;
133+
private Object[] grow() {
134+
return grow(size + 1);
135+
}
136+
137+
private Object[] grow(int minCapacity) {
138+
// 适用 Arrays.copyOf 进行复制,扩容
139+
return elementData = Arrays.copyOf(elementData,
140+
newCapacity(minCapacity));
86141
}
87142

88-
/*
89-
* Private remove method that skips bounds checking and does not
90-
* return the value removed.
91-
*/
92-
private void fastRemove(int index) {
93-
modCount++;
94-
int numMoved = size - index - 1;
95-
if (numMoved > 0)
96-
System.arraycopy(elementData, index+1, elementData, index,
97-
numMoved);
98-
elementData[--size] = null; // clear to let GC do its work
143+
private int newCapacity(int minCapacity) {
144+
// overflow-conscious code
145+
int oldCapacity = elementData.length;
146+
// 扩容为原来的1.5倍
147+
int newCapacity = oldCapacity + (oldCapacity >> 1);
148+
if (newCapacity - minCapacity <= 0) {
149+
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
150+
return Math.max(DEFAULT_CAPACITY, minCapacity);
151+
if (minCapacity < 0) // overflow
152+
throw new OutOfMemoryError();
153+
return minCapacity;
154+
}
155+
return (newCapacity - MAX_ARRAY_SIZE <= 0)
156+
? newCapacity
157+
: hugeCapacity(minCapacity);
158+
}
159+
160+
private static int hugeCapacity(int minCapacity) {
161+
if (minCapacity < 0) // overflow
162+
throw new OutOfMemoryError();
163+
// 虽然定义了最大的容量Integer.MAX_VALUE-8,但有以下情况可以让容量达到Integer.MAX_VALUE
164+
return (minCapacity > MAX_ARRAY_SIZE)
165+
? Integer.MAX_VALUE
166+
: MAX_ARRAY_SIZE;
167+
}
168+
```
169+
170+
## 4. 静态内部类SubList
171+
172+
```java
173+
/** ArrayList 中的 subList 方法 */
174+
public List<E> subList(int fromIndex, int toIndex) {
175+
// 调用父类AbstractList中的subListRangeCheck方法进行数组下标检查
176+
subListRangeCheck(fromIndex, toIndex, size);
177+
// 返回的内部类 SubList,不可后续进行强转
178+
return new SubList<>(this, fromIndex, toIndex);
99179
}
100180
```
101181

102-
首先判断传入对象是否为Null,如果为null,则遍历数组中已有值的元素,与传入对象进行比较是否为Null.如果为空则通过fastRemove删除相对应下标的对象,如果传入对象不为null,则通过equals方法进行比较,同样通过fastRemove方法删除;
182+
### 结构
183+
184+
```java
185+
/**
186+
* 该类和 ArrayList 非继承关系
187+
*/
188+
private static class SubList<E> extends AbstractList<E> implements RandomAccess
189+
```
103190

104-
fastRemove:如果需要移动,调用底层System.arraycopy方法将index后的对象往前复制以为,并将数组的最后一个元素值设置为null,即释放了对此对象的引用
191+
### 属性
105192

106-
######判断是否包含此对象:contains
107-
源码:
193+
```java
194+
private final ArrayList<E> root; // 父类,指当前的 ArrayList
195+
private final SubList<E> parent;
196+
private final int offset;
197+
private int size;
108198
```
109-
public boolean contains(Object o) {
110-
return indexOf(o) >= 0;
199+
200+
### 构造
201+
202+
```java
203+
/** SubList构造函数将原来的List和其部分属性赋值给了自己的相应属性,返回了父类的视图(View) */
204+
205+
public SubList(ArrayList<E> root, int fromIndex, int toIndex) {
206+
this.root = root;
207+
this.parent = null;
208+
this.offset = fromIndex;
209+
this.size = toIndex - fromIndex;
210+
this.modCount = root.modCount;
111211
}
112212

113-
public int indexOf(Object o) {
114-
if (o == null) {
115-
for (int i = 0; i < size; i++)
116-
if (elementData[i]==null)
117-
return i;
118-
} else {
119-
for (int i = 0; i < size; i++)
120-
if (o.equals(elementData[i]))
121-
return i;
122-
}
123-
return -1;
213+
private SubList(SubList<E> parent, int fromIndex, int toIndex) {
214+
this.root = parent.root;
215+
this.parent = parent;
216+
this.offset = parent.offset + fromIndex;
217+
this.size = toIndex - fromIndex;
218+
this.modCount = parent.modCount;
124219
}
125220
```
126221

127-
判断是否存在该对象,需要遍历整个ArrayList的元素,如果传入对象为空,则直接判断已有元素是否为null,如果返回null,则返回true;如果传入对象不为null,则通过equals方法找寻是否有相等元素,有则返回true
222+
### 操作
128223

129-
另外还有一个lastIndexOf的方法,与indexOf区别在
130-
```
131-
public int lastIndexOf(Object o) {
132-
if (o == null) {
133-
for (int i = size-1; i >= 0; i--)
134-
if (elementData[i]==null)
135-
return i;
136-
} else {
137-
for (int i = size-1; i >= 0; i--)
138-
if (o.equals(elementData[i]))
139-
return i;
140-
}
141-
return -1;
224+
```java
225+
/** 添加 */
226+
public void add(int index, E element) {
227+
rangeCheckForAdd(index); // 下标检查
228+
checkForComodification(); // fail-fast 检查
229+
root.add(offset + index, element); // 调用的是 ArrayList 的 add 方法
230+
updateSizeAndModCount(1);
142231
}
143232
```
233+
234+
SubList单独定义了set、get、size、add、remove等操作方法,操作了ArrayList的同一个elementData数组,即对SubList进行修改时,也会影响到ArrayList的数据。
235+

0 commit comments

Comments
 (0)