优先选ArrayList:随机访问多、频繁get/set或for循环遍历时;LinkedList内存开销大、GC压力高,固定大小场景应预设容量或用Arrays.asList。
随机访问多就选
如果代码里频繁用
、
或遍历用传统 for 循环(
几乎总是更优。它的底层是数组,
是 O(1) 时间复杂度,而
要从头或尾开始跳节点,平均 O(n/2),实际慢好几倍。
常见错误现象:把
当成“万能快链表”,在日志聚合、分页数据缓存等场景下盲目替换
,结果
变成
性能瓶颈
。
的
直接算内存偏移,无分支、无指针跳转
的
会先比对索引离头近还是离尾近,再决定正向/反向遍历 —— 这个判断本身就有开销
JVM 对数组连续内存的预取(prefetch)友好,
遍历时 CPU 缓存命中率高得多
头尾频繁增删才值得考虑
真正有优势的场景非常窄:只在头或尾做大量
、
、
、
,且几乎不用随机访问。比如实现栈(
)、队列(
)的底层容器,或者消息缓冲区的双端写入。
注意:
和
在
中仍是 O(n),因为必须先
找到位置 —— 这点很多人误以为是 O(1)。
立即学习
“
Java免费学习笔记(深入)
”;
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
尾部
均摊 O(1),但头部或中间插入要移动后续所有元素,O(n)
头尾操作确实是 O(1),但每个元素额外占用两个指针内存(8
字节
× 2,在 64 位 JVM + 压缩指针下可能为 12 字节)
现代 JVM 对小对象分配优化极好,
扩容时的数组复制开销,常被低估但实际可控
别用
替代
如果你需要高效双端操作,优先看
,而不是
。前者是循环数组实现,内存局部性好、无指针开销、GC 压力小,所有操作(
、
、
、
)都是 O(1) 且常数因子更低。
实现了
和
接口,容易让人误以为它是标准队列实现 —— 但 JDK 自己的文档都明确建议:“This class is likely to be faster than
when used as a stack, and faster than
when used as a queue.”(指
)
不允许
元素,
允许 —— 如果业务逻辑依赖
,才是少数必须用
的理由
的迭代器(
)是 fail-fast,但它的
支持双向遍历;
只提供单向迭代器
扩容机制和内存占用差异不能忽略
初始容量为 10,扩容时按 1.5 倍增长(
);
没有容量概念,每加一个元素就新建一个
对象。这意味着:
存 1000 个
,
占用约 1000 × 4 字节(int 基本类型)+ 数组对象头 ≈ 4KB;
是 1000 × (
对象头 + 3 个引用字段) ≈ 24–32KB,差一个数量级
扩容会产生旧数组的 GC 压力,但只发生在增长拐点;
每次
都触发一次小对象分配,GC 频率更高
如果集合大小基本固定(如配置项列表、枚举映射),直接用
或指定初始容量的
,避免扩容
真实项目里,看到用
存几百个 DTO 并反复
,基本可以判定是历史包袱或对集合特性理解有偏差 —— 这种地方改用
,往往比加机器更管用。
ArrayListget(i)set(i, e)for (int i = 0; i ),ArrayListgetLinkedListLinkedListArrayListget(999)ArrayListgetLinkedListgetArrayListLinkedListLinkedListaddFirst()addLast()removeFirst()removeLast()push/popoffer/polladd(index, e)remove(index)LinkedListget(index)ArrayListadd(e)LinkedListArrayListLinkedListArrayDequeArrayDequeLinkedListaddFirstaddLastpollFirstpollLastDeque queue = new ArrayDeque<>();
queue.offerLast("a");
queue.pollFirst(); // 比 LinkedList 快,且不产生多余对象 LinkedListQueueDequeStackLinkedListArrayDequeArrayDequenullLinkedListnullLinkedListLinkedListIteratorListIteratorArrayDequeArrayListoldCapacity + (oldCapacity >> 1)LinkedListNodeIntegerArrayListLinkedListNodeArrayListLinkedListaddArrays.asList(...)ArrayList(int initialCapacity)LinkedListget(i)ArrayList