应避免用ArrayList模拟队列,因其remove(0)为O(n);推荐ArrayDeque(非null)或LinkedList;遍历时删除须用迭代器remove()或removeIf();HashMap无序,需有序用LinkedHashMap或TreeMap;Arrays.asList()返回集合不可修改,需转ArrayList。

用 ArrayList 当队列频繁调用 remove(0)
这看起来像在模拟队列出队,但 ArrayList 底层是数组,remove(0) 会把后面所有元素向前复制一遍,时间复杂度是 O(n)。高频操作下性能断崖式下跌。
- 真要当队列用,改用
LinkedList(支持 O(1) 的头尾增删)或更推荐的ArrayDeque(无同步开销、内存连续、实际更快) -
ArrayDeque不接受null,如果业务允许为空,得提前判空或换LinkedList - 别被名字误导:
LinkedList实现了Queue接口,但随机访问(get(i))仍是 O(n),别拿来当列表查下标
遍历集合时直接调用 remove() 导致 ConcurrentModificationException
这是新手最常撞墙的地方:一边用 for-each 或迭代器遍历,一边用集合自身的 remove() 方法删元素,触发快速失败机制。
- 正确做法是用迭代器的
remove()方法:it.remove()—— 它会同步更新内部modCount - Java 8+ 可用
removeIf():比如list.removeIf(x -> x % 2 == 0),简洁且线程安全(单线程场景) - 想边遍历边新增?不行。哪怕用
it.add()也不行(Iterator不支持 add),得先收集待添加项,遍历完再批量加
把 HashMap 当作有序容器依赖插入顺序
HashMap 不保证任何顺序——JDK 8 以后底层用红黑树优化链表,但遍历顺序仍取决于哈希值和扩容时机,完全不可靠。
- 需要按插入顺序遍历,用
LinkedHashMap,它额外维护双向链表 - 需要按 key 自然序或自定义序,用
TreeMap,但注意它用的是红黑树,不是哈希,查找是 O(log n) -
LinkedHashMap的accessOrder = true模式可用于 LRU 缓存,但构造时必须显式传参,否则默认是插入序
用 Arrays.asList() 返回的集合直接调用 add() 或 clear()
这个方法返回的是 Arrays 内部的静态类,它包装了原始数组,大小固定。所有结构性修改都会抛 UnsupportedOperationException。
立即学习“Java免费学习笔记(深入)”;
- 常见错误:写
List→ 直接崩溃list = Arrays.asList("a", "b"); list.add("c"); - 如果后续要增删,必须转成真正可变集合:
new ArrayList(Arrays.asList(...)) - 注意:这个转换只复制引用,原数组和新
ArrayList的元素对象仍是同一个,改对象内容会互相影响
HashMap 顺序问题,在测试数据少时碰巧一致,上线后数据量一上去就错乱。










