概念
有限个相同类型变量的有序集合
使用一块连续的内存区域,进行顺序存储
访问时通过下标进行访问
数组的下标是什么
即:偏移量offset
如果数组的首元素为a,a[0]即偏移量为0的位置。
为什么下标从0开始
下标为偏移量,所以如果从1开始第一个元素的偏移量为0.依此类推每次都要进行一次-1的减法操作。从0开始减少一次减法操作,性能达到极致。
数组操作的时间复杂度
增
- 尾部添加,那么只需要在最后一位添加上新的元素即可,所以时间复杂度为O(1)。
- 头部添加或中间添加,则需要对添加位后面的所有元素进行移位操作。最坏的时间复杂度是O(n)即头部添加全部需要移位。
删
- 同样分尾部删除位O(1)
- 头部删除或中间位删除则需要进行移位,最坏时间复杂度O(n)
改
- 数组的修改比较简单,只重新赋值某位即可,所以是O(1)
查
- 前面说了数组使用的是一块连续的内存区域,并且使用偏移量进行元素访问。所以我们可以根据下表快速获取到某个元素。所以查询时间复杂度O(1)
优缺点
根据数组操作的时间复杂度,所以数组特别适合于随机访问、查询类的操作。但由于增删的时间复杂度是O(n),所以不适合随机写、删除多的场景。遍历时使用fori遍历非常高效。但是根据数组的定义,数组是一个有限集合,所以存在resize问题。这时候就要进行数组拷贝。相对比较影响应能。
简单手写一个arrayList,不具备使用价值,只是简单体现一下实现复杂度和resize步骤。
public class WmArray {
private transient int[] array;
private transient int size;
public WmArray(int size) {
this.array = new int[size];
this.size = 0;
}
public void add(int element) {
checkResize();
array[size++] = element;
}
private void checkResize() {
if (size >= array.length) {
resize();
}
}
private void resize() {
int[] re = new int[size * 2];
System.arraycopy(array, 0, re, 0, array.length);
array = re;
}
public void add(int index, int element) {
checkResize();
for (int i = size - 1; i >= index; i--) {
array[i + 1] = array[i];
}
array[index] = element;
}
public void remove(int index) {
if(index > size){
throw new IllegalArgumentException("越界");
}
for (int i = index; i < size; i++) {
array[i] = array[i + 1];
}
array[size--] = 0;
}
public void update(int index,int element){
array[index] = element;
}
public int get(int index){
return array[index];
}
@Override
public String toString() {
return "WmArray{" +
"array=" + Arrays.toString(array) +
", size=" + size +
'}';
}
}