终于开始写博客了,前面想了很多次写博客,但是都没有动笔,苦于不知如何表述,最近开始复习集合,想通过写博客加深自己的印象,记录自己的理解,该篇文章从构造方法入手,然后到常用的一些方法,摘取JDK中源码,在上面加上自己的理解,有不对的不严谨的地方还望大佬们多多指正
概述
继承AbstractList抽象类,实现List接口底层用数组存放数据,默认容量大小为10扩容倍数为1.5倍线程不安全的支持随机访问,查看元素较为简单添加、删除操作较为烦琐
底层源码
相关属性
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess
, Cloneable
, java
.io
.Serializable
{
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
;
private int size
;
}
构造方法
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
;
}
public ArrayList(Collection
<? extends E> c
) {
elementData
= c
.toArray();
if ((size
= elementData
.length
) != 0) {
if (elementData
.getClass() != Object
[].class)
elementData
= Arrays
.copyOf(elementData
, size
, Object
[].class);
} else {
this.elementData
= EMPTY_ELEMENTDATA
;
}
}
添加操作
public boolean add(E e
) {
ensureCapacityInternal(size
+ 1);
elementData
[size
++] = e
;
return true;
}
public void add(int index
, E element
) {
rangeCheckForAdd(index
);
ensureCapacityInternal(size
+ 1);
System
.arraycopy(elementData
, index
, elementData
, index
+ 1,
size
- index
);
elementData
[index
] = element
;
size
++;
}
关于arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 方法 将原数组的指定一段拷贝到目标数组的指定位置
src 原数组int 原数组开始拷贝的位置dest 目标数组destPos 目标数组接收拷贝的位置length 拷贝的长度
扩容相关操作
private void ensureCapacityInternal(int minCapacity
) {
if (elementData
== DEFAULTCAPACITY_EMPTY_ELEMENTDATA
) {
minCapacity
= Math
.max(DEFAULT_CAPACITY
, minCapacity
);
}
ensureExplicitCapacity(minCapacity
);
}
private void ensureExplicitCapacity(int minCapacity
) {
modCount
++;
if (minCapacity
- elementData
.length
> 0)
grow(minCapacity
);
}
private void grow(int minCapacity
) {
int oldCapacity
= elementData
.length
;
int newCapacity
= oldCapacity
+ (oldCapacity
>> 1);
if (newCapacity
- minCapacity
< 0)
newCapacity
= minCapacity
;
if (newCapacity
- MAX_ARRAY_SIZE
> 0)
newCapacity
= hugeCapacity(minCapacity
);
elementData
= Arrays
.copyOf(elementData
, newCapacity
);
}
private static final int MAX_ARRAY_SIZE
= Integer
.MAX_VALUE
- 8;
private static int hugeCapacity(int minCapacity
) {
if (minCapacity
< 0)
throw new OutOfMemoryError();
return (minCapacity
> MAX_ARRAY_SIZE
) ?
Integer
.MAX_VALUE
:
MAX_ARRAY_SIZE
;
}
关于Arrays.copyOf(Object[] original,int newLength)方法 将指定数组的长度改变为newLength
original 原数组newLength 新数组的长度,该长度可能小于原数组长度,所以该方法也可以缩容也可以扩容
删除元素
public E
remove(int index
) {
rangeCheck(index
);
modCount
++;
E oldValue
= elementData(index
);
int numMoved
= size
- index
- 1;
if (numMoved
> 0)
System
.arraycopy(elementData
, index
+1, elementData
, index
,
numMoved
);
elementData
[--size
] = null
;
return oldValue
;
}
public boolean remove(Object o
) {
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 void trimToSize() {
modCount
++;
if (size
< elementData
.length
) {
elementData
= (size
== 0)
? EMPTY_ELEMENTDATA
: Arrays
.copyOf(elementData
, size
);
}
}
清空操作
public void clear() {
modCount
++;
for (int i
= 0; i
< size
; i
++)
elementData
[i
] = null
;
size
= 0;
}
迭代器相关
public Iterator
<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor
;
int lastRet
= -1;
int expectedModCount
= modCount
;
public boolean hasNext() {
return cursor
!= size
;
}
@SuppressWarnings("unchecked")
public E
next() {
checkForComodification();
int i
= cursor
;
if (i
>= size
)
throw new NoSuchElementException();
Object
[] elementData
= ArrayList
.this.elementData
;
if (i
>= elementData
.length
)
throw new ConcurrentModificationException();
cursor
= i
+ 1;
return (E
) elementData
[lastRet
= i
];
}
public void remove() {
if (lastRet
< 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList
.this.remove(lastRet
);
cursor
= lastRet
;
lastRet
= -1;
expectedModCount
= modCount
;
} catch (IndexOutOfBoundsException ex
) {
throw new ConcurrentModificationException();
}
}
}
总结
modCount字段记录内部结构发生修改的次数,元素添加、删除次数添加元素顺序:计算所需的最小容量(size+1)->判断是否需要扩容->进行扩容->添加元素扩容时进行判断,如果1.5倍的容量大小不能满足,则直接扩容成size+1大小,最大容量为Integer.MAX_VALUE提供了手动缩容方法,但内部没有调用(我没找到),将内部数组大小缩为size大小对于序列化这个问题,还不是很理解,所以就没有写出来了