collections.swap() 要求列表可变且索引合法:arrays.aslist() 返回的不可变列表虽支持 swap()(因 set() 可用),但后续 add()/remove() 会抛 unsupportedoperationexception;索引必须满足 0 ≤ i,j
swap() 方法只能用于可变列表,不可用于 Arrays.asList() 返回的包装类
调用
Collections.swap()时如果传入的是Arrays.asList()的返回值,运行时不会报错,但后续修改可能抛出UnsupportedOperationException——因为该方法返回的是Arrays$ArrayList(非java.util.ArrayList),底层数组不可扩容、也不支持结构修改(如add()、remove()),而swap()内部依赖set(),恰好是允许的;但很多开发者误以为“能 swap 就代表可变”,结果在别处调add()才暴露问题。稳妥做法是显式转为真正可变的
ArrayList:List<string> list = new ArrayList(Arrays.asList("a", "b", "c"));</string>再调用
swap()才无后顾之忧。索引越界会直接抛 IndexOutOfBoundsException,不静默失败
Collections.swap(list, i, j)要求i和j都满足0 ≤ i 且 <code>0 ≤ j 。任一越界都会立即抛异常,不会尝试容错或截断。
- 常见错误:把
list.size()当成合法最大索引(实际最大合法索引是list.size() - 1)- 混淆场景:想交换首尾元素,写成
swap(list, 0, list.size())→ 必炸- 安全写法示例:
Collections.swap(list, 0, list.size() - 1); // 交换首尾swap() 是原地操作,不创建新列表,也不改变列表大小
它只交换两个位置上的引用(对对象类型)或值(对基本类型包装类),其余元素顺序和数量完全不变。这意味着:
- 无需接收返回值(方法返回
void)- 对
LinkedList效率较低:因为要分别遍历到第i和第j个节点,时间复杂度 O(max(i, j))- 对
ArrayList效率高:本质是两次get()+ 两次set(),O(1)- 注意并发:该方法不加锁,多线程环境下需自行同步
泛型擦除不影响 swap,但要注意 null 安全
Collections.swap()是泛型静态方法,擦除后实际操作的是Object引用,所以能安全交换任意引用类型。但它不校验null——如果列表中某位置是null,交换照常进行,不会报错也不会跳过。例如:
List<string> list = Arrays.asList("a", null, "c");<br>Collections.swap(list, 0, 1); // 结果:[null, "a", "c"]</string>如果你的业务逻辑不能容忍
null出现在某些位置,得在调用swap()前自己检查,它不会帮你拦。实际用的时候,最易忽略的是列表实现类的可变性边界——看着像
ArrayList,未必真是;还有就是索引习惯性多写 1,一跑就崩。











