1、通过参数构造
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);
}
}
通过int类型 initialCapacity 初始容量参数,构造ArrayList对象,首先判断这个参数,如果大于零,则new 一个大小为参数initialCapacity的Object数组对象赋给 elementDate
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
创建了一个私有的空的Object数组
2、无参构造
/**
* Constructs an empty list with an initial capacity of ten.
构造一个初始容量为10的空list
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_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.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
了解了构造方法,可以构造出一个list,然后是添加元素
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
3、使用add方法
给list添加一个元素,首先认识 ensureCapacityInternal(size + 1) 这个方法的作用,ensure Capacity Internal 确保内部容量
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
size只是一个私有变量
//确保容量
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//calculate capacity 计算容量
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
//确保清楚的容量
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
计算容量方法中,当list在放第一个元素时,minCapacity = 1,elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA,所以会进入if,执行 Math.max(DEFAULT_CAPACITY, minCapacity);比较两个值,返回大的,这里因为 DEFAULT_CAPACITY = 10,所以返回 10
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
//记录list列表结构被修改的次数
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
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);
}
这个方法进行了很多比较,int oldCapacity = elementData.length = 0,int newCapacity = oldCapacity + (oldCapacity >>1),(oldCapacity >>1) 位移运行,右移1位,等于oldCapacity/2 = 0/2 = 0,newCapacity = 0,小于 minCapacity ,所以将 minCapacity 赋给 newCapacity = 10,elementData = Arrays.copyOf(elementData, newCapacity);
public static void main(String[] args) {
String[] str1 = {"123","234"};
for(String string : str1){
System.out.print(string + "\t");
}
String[] str2 = Arrays.copyOf(str1,5);
System.out.println();
for(String string : str2){
System.out.print(string + "\t");
}
}
执行结果:
4、移除元素
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;
}
首先判断移除的对象是否为空,不为空,则循环遍历list中的元素,然后使用equals方法进行比较,找到元素,然后记录index,使用 fastRemove(index) 方法移除
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
Remove元素,需要改变list列表结构,所以modCount++记录列表结构变化次数,然后是计算需要移动元素个数 numMoved = size - index -1,然后使用 arraycopy方法
String[] srcArr = {"1","2","3","4"};
for(String str : srcArr){
System.out.println(str);
}
String[] destArr = new String[10];
System.arraycopy(srcArr,0,destArr,0,3);
System.out.println("========destArr=========");
for(String str : destArr){
System.out.println(str);
}
执行结果:
1
2
3
4
========destArr=========
1
2
3
null
null
null
null
null
null
null
elementData[--size] = null 将数组最后一个位置赋为null,等待gc回收,并且 size - 1
5、根据索引位置移除元素
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; // clear to let GC do its work
return oldValue;
}
rangeCheck(index)方法判断 index 是否越界,如果超出数组大小,则抛出异常