Java-ArrayList

JDK8版本

1
2
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable

ArrayList 数组列表,分别实现了列表、随机访问、可克隆、序列化,继承了抽象列表,其关系如下所示:

1.几个参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static final long serialVersionUID = 8683452581122892189L;


private static final int DEFAULT_CAPACITY = 10;


private static final Object[] EMPTY_ELEMENTDATA = {};


private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};


transient Object[] elementData; // non-private to simplify nested class access


private int size;

2.主要方法

构造方法

如果是ArrayList arrayList=new ArrayList(20);只初始化了一次,算没扩容吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}

public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

传入另一个集合,先将collection转为数组,然后copy到elementData中

1
2
3
4
5
6
7
8
9
10
11
12
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// defend against c.toArray (incorrectly) not returning Object[]
// (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}

3.trimToSize()修剪大小到size

1
2
3
4
5
6
7
8
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}

4. 增加容量(这个是给用户调用的,ArrayList内部没有调用)

如果要大批量插入数据,那么调用该函数主动增加容量

1
2
3
4
5
6
7
8
9
public void ensureCapacity(int minCapacity) {
if (minCapacity > elementData.length
&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
&& minCapacity <= DEFAULT_CAPACITY)) {
modCount++;
grow(minCapacity);
}
}
用到了grow() ,newCapacity(minCapacity) ,hugeCapacity(int minCapacity)方法

5.得到O地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int indexOfRange(Object o, int start, int end) {
Object[] es = elementData;
if (o == null) {
for (int i = start; i < end; i++) {
if (es[i] == null) {
return i;
}
}
} else {
for (int i = start; i < end; i++) {
if (o.equals(es[i])) {
return i;
}
}
}
return -1;
}

6.扩容

​ JDK11去掉了

add方法

1
2
3
4
5
6
7
8
9
10
11
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
1
2
3
4
5
6
7
8
9
10
11
/**
* This helper method split out from add(E) to keep method
* bytecode size under 35 (the -XX:MaxInlineSize default value),
* which helps when add(E) is called in a C1-compiled loop.
*/
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}

推荐阅读https://snailclimb.gitee.io/javaguide/#/docs/java/collection/ArrayList%E6%BA%90%E7%A0%81+%E6%89%A9%E5%AE%B9%E6%9C%BA%E5%88%B6%E5%88%86%E6%9E%90?id=_1-arraylist-%e7%ae%80%e4%bb%8b