数组:是一种线性表数据结构,用一组连续存储空间,存储相同类型的数据。java
数据排成一条线同样的存储结构,在线性表中,数据之间相互关系只有先后关系,除了数组以外,还有链表、队列、栈等。算法
与线性表对应的就是非线性表结构,数据之间不止简单的先后关系,好比:二叉树、堆、图等。数组
数组不只要在逻辑上连续,也要在物理上连续。在内存中就要求必须是连续存储,从而致使数组在新增或删除一个数据的时候,为了保证连续性,就须要作大量数据搬移操做。数据结构
同时数组也具备"随机访问"特性,能够根据下标直接访问数据中的数据。计算机会给每块内存分配地址,经过寻址公式计算出内存地址,就能够直接访问。性能
这个公式也能够解释下为何数组下标是从0开始的?优化
//base_address为首地址,i为数组下标,data_type_size为数组中每一个元素所占大小 a[i]_address = base_address + i * data_type_size
“数组适合查找,查找操做的时间复杂度为O(1)”,这句话表达不够准确,数组更加适合查找操做,可是查找的时间复杂度并不为O(1),即便排好序的数组,使用二分查找时间复杂度也为O(logn),数组支持随机访问,根据下标随机访问的时间复杂度为O(1)。code
假设一个数组长度为n,将一个数据插入到第k个位置,就须要将k到n的数据所有日后移一位,这样最好的时间复杂度为O(1),最坏时间复杂度为O(n),平均时间复杂度为O(n)。队列
若是数组中数据有序,插入新数据就须要按照刚才的方法;若是数据无序,则能够进行优化,最简单的办法就是直接将第k位数据搬移到数组最后,将新元素直接放入第k位。内存
删除和插入同样,为了保持连续性,须要进行搬移数据,最好的时间复杂度为O(1),最坏时间复杂度为O(n),平均时间复杂度为O(n)。ci
优化:在特殊场景下,能够将屡次删除操做集中一块儿进行,能够先记录下已经删除的数据。每次的删除操做并非真正地搬移数据,只是记录数据已经被删除。当数组没有更多空间存储数据时,咱们再触发执行一次真正的删除操做,这样就大大减小了删除操做致使的数据搬移。(JVM 标记清除垃圾回收算法的核心思想)
Java 自己就会作越界检查,数组下标越界就会抛出 java.lang.ArrayIndexOutOfBoundsException。
//扩容 newElementData = Arrays.copyOf(oldElementData, newCapacity); //复制 System.arraycopy(被复制的数组A, 从A哪一个下标开始复制, 复制到哪一个数组B, 复制到B从哪一个下标开始, 复制长度); //实现元素右移 System.arraycopy(elementData, index, elementData, index + 1, size - index);