hello啊,各位观众姥爷们!!!本baby今天来报道了!哈哈哈哈哈嗝
特性 | ArrayList | LinkedList |
---|---|---|
存储结构 | 基于动态数组 | 基于双向链表 |
内存分配 | 连续内存块 | 非连续内存,节点分散存储 |
元素访问 | 通过索引直接寻址(时间复杂度 O(1)) | 需要遍历链表(时间复杂度 O(n)) |
插入/删除 | 需要移动元素(时间复杂度 O(n)) | 修改指针(时间复杂度 O(1),但需先遍历到位置) |
空间开销 | 仅存储数据和数组容量,内存紧凑 | 每个节点额外存储前驱和后继指针,内存占用更高 |
ArrayList
list.get(1000); // 直接定位到数组第1000个位置
LinkedList
index < size/2
从头开始)。list.get(1000); // 需要遍历至少1000个节点
尾部插入(Add)
中间插入(Add at Index)
i
处插入元素,需移动 n - i
个元素。删除(Remove)
ArrayList
Integer
为4字节)。LinkedList
ArrayList
newCapacity = oldCapacity + (oldCapacity >> 1)
(即1.5倍)。LinkedList
list.get(i)
)。// ArrayList
List<Integer> arrayList = new ArrayList<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
arrayList.add(i); // 均摊 O(1)
}
System.out.println("ArrayList 尾部插入耗时: " + (System.currentTimeMillis() - start) + "ms");
// LinkedList
List<Integer> linkedList = new LinkedList<>();
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
linkedList.add(i); // O(1)
}
System.out.println("LinkedList 尾部插入耗时: " + (System.currentTimeMillis() - start) + "ms");
结果:
// ArrayList
start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
arrayList.add(0, i); // 每次插入需移动所有元素,O(n)
}
System.out.println("ArrayList 头部插入耗时: " + (System.currentTimeMillis() - start) + "ms");
// LinkedList
start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
linkedList.add(0, i); // O(1)
}
System.out.println("LinkedList 头部插入耗时: " + (System.currentTimeMillis() - start) + "ms");
结果:
迭代器性能
ListIterator
,支持双向遍历)。线程安全性
Collections.synchronizedList
或 CopyOnWriteArrayList
。序列化与克隆
clone()
,实现浅拷贝。维度 | ArrayList | LinkedList |
---|---|---|
数据结构 | 动态数组 | 双向链表 |
访问效率 | O(1)(随机访问) | O(n) |
插入/删除 | O(n)(需移动元素) | O(1)(已知位置)或 O(n)(需遍历) |
内存占用 | 低(连续存储) | 高(每个节点额外指针开销) |
适用场景 | 随机访问、尾部操作、内存敏感 | 频繁头部/中间插入删除、实现队列/栈 |
选择建议: