collections.sort() 排序前需确保元素非null且类型一致,否则抛classcastexception;collections.reverse()是原地操作不返回新集合;synchronizedlist仅同步单方法调用,复合操作需手动加锁;collections.max()遇空集合直接抛异常。

用 Collections.sort() 排序前先确认元素可比较
直接对 ArrayList 调用 Collections.sort() 报 ClassCastException?大概率是集合里塞了 null,或者混了不同类型的对象(比如 String 和 Integer)。Java 默认要求元素实现 Comparable,且类型一致。
实操建议:
- 如果元素本身不可比(比如自定义类),必须传入
Comparator,不能依赖无参重载 -
null值会直接抛异常——哪怕只一个null,整个排序就崩,得提前过滤或用Comparator.nullsFirst() - 对
LinkedList排序性能较差,内部会转成数组再归并;高频排序优先用ArrayList
别用 Collections.reverse() 反转原始集合时忽略它不返回新集合
调用 Collections.reverse(list) 后发现原列表被改了,但没拿到“新反转结果”?因为它是原地操作,返回 void,不是返回新集合。新手常误以为它像 Stream.reversed() 那样生成副本。
实操建议:
- 想保留原集合不变,得先复制:
new ArrayList(originalList)再反转 - 对
Arrays.asList()返回的集合调用reverse()会生效,但它底层绑定原数组,修改后原数组也变 - 如果只是临时遍历倒序,用
for (int i = list.size()-1; i >= 0; i--)比创建副本更轻量
Collections.synchronizedList() 不等于线程安全的全部保障
加了 Collections.synchronizedList(new ArrayList()) 还出现 ConcurrentModificationException 或数据错乱?问题出在:它只同步单个方法调用,不保证复合操作原子性。比如 if (!list.isEmpty()) list.remove(0); 中的判断和删除仍是两步,中间可能被其他线程插队。
实操建议:
- 迭代时必须手动同步:
synchronized (list) { for (E e : list) { ... } },否则仍可能抛异常 - 高频读写场景下,
CopyOnWriteArrayList更合适——但注意写操作开销大,不适合写多场景 - 同步包装类不改变底层集合行为,比如
synchronizedList的subList()返回的子列表仍是非同步的
查找最大/最小值时小心 Collections.max() 的空集合陷阱
Collections.max(list) 直接抛 NoSuchElementException?只要 list 是空的,哪怕它是个合法的空 ArrayList,也会炸。它不像 Stream.max() 那样返回 Optional,也不接受默认值参数。
实操建议:
- 必须提前判空:
if (!list.isEmpty()) max = Collections.max(list); - 若需默认值逻辑,自己封装一层,别指望
Collections工具类帮你兜底 - 对
null元素,除非用了显式Comparator处理null,否则同样抛NullPointerException
这些方法看着简单,但每个都卡在「边界条件」上:空、null、类型混杂、复合操作、迭代并发……真正用稳,得盯着它们到底动了谁、没动谁、在哪一步断掉。









