数组
- 数组是一种线性表数据结构,用一组连续的内存空间,来存储一组具有相同类型的数据,
- 计算机给每个内存单元都分配了一个地址,然后要找到这个地址需要用一个寻址公式
a[i] = baseAddress + i * dataTypeSize
- 如果下标不是从0开始而是从1开始的话,以上的公式的i需要在进行一个-1的操作,等于浪费了一次计算
- 特点:
- 高效的随机访问
- 低效的插入和删除(需要移动后续的元素)
关于list的add方法解读
public class myList<E> {
//list元素个数
private int size;
//默认初始化的长度
private static final int DEFAULT_CAPACITY = 10;
//为空的list
private static final Object[] EMPTY_ELEMENTDATA = {};
//list被修改的次数
protected transient int modCount = 0;
//默认初始化的数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//存储元素的数组
transient Object[] elementData;
//list最大的长度
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
/**
*返回当前能存储的容量
* @param elementData 当前list存数据的数组
* @param minCapacity 当前list里元素个数+1
* @return
*/
private static int calculateCapacity(Object[] elementData, int minCapacity) {
//如果当前数组为空数组,就取默认初始化的长度与当前元素个数+1 比较大的那个
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
/**
* 确保list安全,防止溢出
* @param minCapacity
*/
private void ensureExplicitCapacity(int minCapacity) {
// 操作数+1
modCount++;
//加了这个元素之后,超过了这个数组所能承受的最大值,就扩容
if (minCapacity - elementData.length > 0) {
grow(minCapacity);
}
}
/**
* 扩容
* @param minCapacity
*/
private void grow(int minCapacity) {
//当前list的长度
int oldCapacity = elementData.length;
//扩容为当前list的1.5倍长度
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 int hugeCapacity(int minCapacity) {
if (minCapacity < 0)
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
}