1、数组的内存地址是连续的,从0起始,使用数组时要注意角标越界
2、数组的删除和新增都需要移动元素,所以速度很慢
数组的新增:
public void insert(int loc,int n){ //时间复杂度 O(n); if(index ++ < size){ for(int i = size - 1; i > loc ; i --){ data[i] = data[i - 1]; //把数据往后移一个 } data[loc] = n; } }
数组的新增就是把数据往后挪一位,删除就是把数据往前进一位
数组的删除:
public void delete(int loc){ // O(n) for(int i = loc ; i < size ; i++){ if(i != size - 1){ //防止越界 data[i] = data[i + 1]; }else{ data[i] = 0; //默认为0 } } index -- ; }
ArrayList中的数组扩容分析:
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; // 旧数组长度 int newCapacity = oldCapacity + (oldCapacity >> 1); // 右移运算加0.5,总体加1.5 if (newCapacity - minCapacity < 0) // 扩容不够 newCapacity = minCapacity; // 直接把实际长度赋给数组 if (newCapacity - MAX_ARRAY_SIZE > 0) // 长度大于int最大值减8 newCapacity = hugeCapacity(minCapacity);比较实际值,最大赋值int的最大值 // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); // 复制数组数据 }
这里将扩容的数组值和实体数组最大值比较目的是为了空间复杂度最小。如果扩容值小,就开辟扩容值那么大的空间,下次需要再扩容。如果扩容值大,直接一次性赋值。
ArrayList不管是初始化还是扩容都会占用内存空间,尽量避免初始化内存空间过大