数据结构:数组
1、 重要成员变量:
size : 已使用的长度
elementData.length : 数组的长度 也就是容量
modCount : 容器被修改的次数, 用于 迭代器遍历的过程中 校验容器是否被修改: 代器初始的时候会赋予它调用这个迭代器的对象的mCount,如何在迭代器遍历的过程中,一旦发现这个对象的mcount和迭代器中存储的mcount不一样那就抛异常
1.操作
1.1操作
System.arraycopy
System.arraycopy(int[] arr, int star,int[] arr2, int start2, length);
第一个参数是要被复制的数组
第二个参数是被复制的数字开始复制的下标
第三个参数是目标数组,也就是要把数据放进来的数组
第四个参数是从目标数据第几个下标开始放入数据
第五个参数表示从被复制的数组中拿几个数值放到目标数组中
比如:
数组1:int[] arr = { 1, 2, 3, 4, 5 };
数组2:int[] arr2 = { 5, 6,7, 8, 9 };
运行:System.arraycopy(arr, 1, arr2, 0, 3);
得到:
int[] arr2 = { 2, 3, 4, 8, 9 };
1.1.1 增加
添加一个元素
public boolean add(E e) {
//判断容量,如果+1之后超出原有大小,就进行扩容
ensureCapacityInternal(size + 1);
//数组最末尾下标+1的位置指向添加的元素
elementData[size++] = e;
return true;
}
指定下标添加元素
public void add(int index, E element) {
rangeCheckForAdd(index);
//判断容量,容量不足进行扩容
ensureCapacityInternal(size + 1);
//讲原来位置在index之后的数据全部对应的移到index+1的位置上
System.arraycopy(elementData, index,
elementData, index + 1,
size - index);
//index指向新插入的数据
elementData[index] = element;
//已用长度+1
size++;
}
//添加一个集合到arrayList中
public boolean addAll(Collection extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew);
将集合转为数组后,整个复制到arraylist的末尾
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
//添加一个集合到arraylist的指定位置上
public boolean addAll(int index, Collection extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
//相当于index之后的数据放到index+要增加集合的长度之后的位置上,将index到index+要增加集合的长度的位置空出来
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
//将整个要增加的集合复制到空出来的位置上
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
1.1.1.2扩容
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 旧容量 + 旧容量右移1位,就是除以2 的 值
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 可能初始化arrayList的时候是0,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);
}
1.1.1.2删除
//删除指定元素
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
//将index+1的元素复制到index上
if (numMoved > 0)
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) {
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;
}
1.1.1.3 获取
//获取某下标元素:根据数组下标获取
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
1.1.1.3 设置
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
1.1.1.3 迭代器
private class Itr implements Iterator {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
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;//每次next()都将游标后移一位
//返回数组中对应游标位置的数据,并将后移前的游标值赋给lastRet
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
//如果中途删除,将当前游标赋给lastRetm让下一次的next获取的数组下标还是当前下标
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}