标准答案

  1. ArrayList 尾部追加均摊 O(1),按索引访问 O(1),中间插入删除需要移动元素。
  2. LinkedList 按索引访问 O(n),节点对象和指针带来内存与缓存开销。
  3. 数组容量固定、开销低,适合长度明确或底层算法;动态集合需要处理扩容。
  4. 集合选择应结合访问模式、数据量、对象生命周期和线程安全要求。

题目解析

ArrayList 连续内存带来较好的局部性和随机访问,LinkedList 只有在已经持有节点位置且频繁插入删除时才可能有优势。若还要按索引或搜索定位,链表的 O(n) 往往抵消插入成本。

数组和 ArrayList 的容量策略会影响扩容复制和内存峰值,已知规模时可以预估容量。集合选择还要结合对象数量、遍历方式和 GC 压力,而不是只看 Big-O。

数据结构性能和线程安全是两个维度。ArrayList 加锁不等于所有复合操作都正确,CopyOnWriteArrayList 也只适合读多写少的特定场景。

常见误区

  • 误区:因为链表插入 O(1) 就默认选 LinkedList。改正:先考虑定位节点、遍历局部性和实际访问模式。
  • 误区:热路径频繁扩容却不估算容量。改正:按数据规模预估初始容量,并监控复制和内存峰值。
  • 误区:把集合线程安全和数据结构选择混为一谈。改正:分别选择访问结构和同步策略,验证复合操作边界。

作者信息