数组
内存特性:定长且连续
定长
:一个数组在内存中一旦被创建,其长度就是一定的,不能够被扩展也不能够被缩短。如果 需要在内存当中将数组的长度进行改变,就需要重新创建一个数组以及将原始数组当中的内容复 制到新数组当中。在Java当中创建对象本身就是一个十分消耗时间和空间的操作,再加上原始元 素的拷贝,将会浪费大量的时间。所以,数组的定长特性导致增删(改变数组长度的增删操作) 慢。
连续
: 指的是在Java中,存在于同一个数组中的所有元素,其内存地址之间是连续有规律 的
ArrayList当中的数组扩容机制
:在ArrayList 内部数组elementData长度不足以容纳新来元素的 情况下,ArrayList会对这个数组进行扩容操作。扩容的时候默认情况下是将数组的长度扩容为 原来的1.5倍。扩容方式是使用位运算符的右移运算,将原始数组长度/2,加上原始数组长度 ,得到扩容之后的新长度。
定长导致增删慢,连续导致遍历快
快速随机访问公式
:目标下标元素内存地址 = 数组的首地址(下标位0的元素的内存地址) + (目标元素下标 * 单个元素大小)。
Java中常见的使用数组进行封装的结构:ArrayList、Vector
链表
分为单链表和双链表:
内存特性:不定长且不连续
不定长:
在同一个链表结构当中,每一个数据都是使用一个独立的节点进行保存的。节点与节点 之间使用引用变量(前驱指针、后继指针)进行关联。在对同一个链表结构当中的节点进行增删 操作的时候,只要改变几个引用变量的取值,就能够实现链表节点的增删,不涉及到新链表的整 体开辟和原始链表元素的拷贝。
不连续:
即使在同一个链表当中的所有节点之间,其内存地址都是不连续的。因为每一个节点都 是单独通过Node节点类型实例化得到的对象。在实例化的过程当中没有办法保证所有的节点之 间内存地址具备连续特性。所以在链表结构当中,如果要按照下标进行节点(数据)访问的话, 需要使用计步器法,每一次查找都从头结点出发,一步一步的进行计步,这种操作十分消耗时 间
不定长导致增删快,不连续导致查找慢
Java中常见的使用链表进行封装的数据结构:LinkedList