集合继承关系图

image-20200515144031807

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* Default initial capacity.
* 容器默认大小
*/
private static final int DEFAULT_CAPACITY = 10;

/**
* Shared empty array instance used for empty instances.
* 当数组的长度被指定为0的时候,elementData使用当前属性
* 有参构造方法,在长度为0 的时候,指向当前数组
*/
private static final Object[] EMPTY_ELEMENTDATA = {};

/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
* 中间状态,只有在元素被添加的时候,才会进行初始化
* 无参构造方法,数组会指向当前属性,因为都是static,final的,所有的空数组都会公用当前属性,减少内存占用
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
* 存储数据的位置
*/
transient Object[] elementData; // non-private to simplify nested class access

/**
* The size of the ArrayList (the number of elements it contains).
*数组大小
* @serial
*/
private int size;

构造方法

  • 无参构造方法,数组指向 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 对象,添加数据时才进行初始化
1
2
3
4
public ArrayList() {
//默认构造方法,数组初始化为DEFAULTCAPACITY_EMPTY_ELEMENTDATA
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
  • 指定容量大小的构造方法
1
2
3
4
5
6
7
8
9
10
11
12
13
public ArrayList(int initialCapacity) {
//指定容量大小的构造方法
if (initialCapacity > 0) {
//如果容量大于0.则初始化数组大小为initialCapacity
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//如果容量为0,那么直接初始化数组为EMPTY_ELEMENTDATA
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
  • 传入一个集合的构造方法
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) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
//父类的引用可以指向子类的实例,但是在使用过程中,如果用object操作会出现异常
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}

常用方法

  • public boolean add(E e) 添加元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 public boolean add(E e) {
//增加修改次数,并且决定是否需要扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
//如果数组还没有初始化
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//最小容量为默认容量和参数的最大值
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}

ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
//增加修改数量
modCount++;

// overflow-conscious code
//如果最小的容量比当前数组的长度要大,那么进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//新数组长度等于原数组长度+原数组长度左移一位,即原数组长度的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果1.5倍原数组还是小于最小容量,那么直接赋值最小容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
//如果新数组长度大于最大数组长度,那么重新赋值为最大数组长度,或者整形最大值
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
//赋值原有数组数据到新的数组上面
elementData = Arrays.copyOf(elementData, newCapacity);
}
  • public void add(int index, E element) 指定位置插入元素
1
2
3
4
5
6
7
8
9
10
11
12
public void add(int index, E element) {
//判断index是否在0-size区间,否则抛出异常
rangeCheckForAdd(index);

//增加修改次数,并且决定是否需要扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
//将index后续的所有数据往后移动一位
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
  • public boolean addAll(Collection<? extends E> c) 增加一个集合元素到当前集合
1
2
3
4
5
6
7
8
9
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
//增加修改次数,并且决定是否需要扩容
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
  • public boolean addAll(int index, Collection<? extends E> c) 从指定位置开始插入一个集合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//判断index是否在0-size区间,否则抛出异常
rangeCheckForAdd(index);

Object[] a = c.toArray();
int numNew = a.length;
//增加修改次数,并且决定是否需要扩容
ensureCapacityInternal(size + numNew); // Increments modCount

int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);

System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
  • public E remove(int index) 删除指定索引上面的元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public E remove(int index) {
//判断index是否在0-size区间,否则抛出异常
rangeCheck(index);

//增加修改次数
modCount++;
E oldValue = elementData(index);

int numMoved = size - index - 1;
if (numMoved > 0)
//将index后续的数组和index交换,把index所在位置的值挪到数组末尾
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work

return oldValue;
}
  • public boolean remove(Object o) 判断对象 o 是否存在于集合,如果存在,删除元素返回 true,否则返回 false,只会删除一次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public boolean remove(Object o) {
//如果o为null,则删除数组第一个null的值,
//如果o不为null,则循环遍历equals方法相等的对象,只删除第一个
//如果找到值,则删除返回true,否则返回false
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
  • public boolean removeAll(Collection<?> c) 原集合 A A-AUB,删除交集
1
2
3
4
5
public boolean removeAll(Collection<?> c) {
//原集合-删除交集
Objects.requireNonNull(c);
return batchRemove(c, false);
}
  • public boolean retainAll(Collection<?> c) 返回交集
1
2
3
4
5
public boolean retainAll(Collection<?> c) {
//返回交集
Objects.requireNonNull(c);
return batchRemove(c, true);
}
  • public List subList(int fromIndex, int toIndex) 返回当前元素的子集,注意对整个子集的修改将会影响到原有集合

  • public void sort(Comparator<? super E> c) 对集合元素排序

  • public int size() 返回数组长度

  • public boolean contains(Object o) 判断元素是否在集合中

1
2
3
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
  • public int indexOf(Object o) 返回元素在集合中的位置,如果不存在,则返回-1
1
2
3
4
5
6
7
8
9
10
11
12
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
  • public int lastIndexOf(Object o) 反向遍历,返回元素在集合中的位置,如果不存在,则返回-1
1
2
3
4
5
6
7
8
9
10
11
12
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
  • public void trimToSize 重置数组空间,释放不需要的空间
1
2
3
4
5
6
7
8
9
public void trimToSize() {
//这个方法的作用是,若数组大小扩容之后是15,只插入了11个元素,调用此方法后可以删除多余的数组占用,数组长度调整为11
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}