Collections.swap() 严格校验索引合法性,越界立即抛出 IndexOutOfBoundsException;内部逐个检查 i 和 j 是否满足 0 ≤ i < size 且 0 ≤ j < size。

Collections.swap() 在交换 List 中指定位置元素时,会执行明确且严格的运行时安全性检查,不是“尽力而为”,而是“越界即报错”。
索引合法性校验:立即抛出 IndexOutOfBoundsException
方法内部会逐个检查两个索引 i 和 j 是否满足:
0 ≤ i 且 0 ≤ j
任一不满足,立刻抛出 IndexOutOfBoundsException,不会静默跳过、截断或容错。
- 常见误写:用
list.size()当作最大合法索引(实际最大是list.size() - 1) - 安全写法:交换首尾元素应写为
Collections.swap(list, 0, list.size() - 1) - 支持
i == j:此时无实际变化,不抛异常,也不做多余操作
列表可变性与结构约束:swap 不等于“可任意修改”
Collections.swap() 依赖 list.set() 实现,因此只要列表支持 set() 操作,就能成功交换。但需注意:
-
Arrays.asList()返回的列表支持swap()(因底层允许set),但不支持add()或remove()—— 后续调用会抛UnsupportedOperationException - 真正稳妥的做法是显式包装:用
new ArrayList(Arrays.asList(...))构造可完全修改的列表 - 不可变列表(如
Collections.unmodifiableList())调用swap()会直接失败
线程安全与 null 处理:由使用者负责
该方法本身不加锁、不同步,也不过滤 null:
立即学习“Java免费学习笔记(深入)”;
- 多线程环境下,若多个线程同时读写同一 List,需外部加锁或使用线程安全容器(如
CopyOnWriteArrayList) - 列表中允许存
null,swap()对null值完全兼容——既不拒绝,也不特殊处理,交换照常进行 - 泛型擦除后操作的是
Object引用,类型安全由编译期泛型保证,运行时不校验实际类型
性能与实现细节:轻量但有结构差异
交换动作本身开销极小,但效率受 List 实现类影响:
-
ArrayList:本质是两次get()+ 两次set(),时间复杂度 O(1) -
LinkedList:需分别遍历到第i和第j个节点,时间复杂度 O(max(i, j)) - 底层语句等价于:
list.set(i, list.set(j, list.get(i))),原子完成,无临时对象创建


















