自定义IntList调用Collections.reverse结果异常,求问题原因
问题原因分析与修复方案
你的IntList类的set方法违反了List接口的约定,这是导致Collections.reverse执行结果异常的根本原因。
核心问题拆解
根据Java官方对List.set(int index, E element)方法的规范,这个方法必须返回该索引位置被替换前的旧值,而不是你设置的新值。但你的实现代码:
@Override public Integer set(int i, Integer e) { return array[i] = e; }
这行代码的逻辑是先把e赋值给array[i],然后返回这个赋值后的结果(也就是e本身),完全不符合方法的约定。
为什么会导致反转异常?
我们来看看Collections.reverse内部的交换逻辑,它依赖swap方法实现首尾元素交换,核心代码简化后是这样的:
private static void swap(List<?> list, int i, int j) { list.set(i, list.set(j, list.get(i))); }
结合你的测试数组[4,2,0,1,3],我们一步步看错误的set方法会怎么破坏这个逻辑:
- 第一次交换索引0和4:
list.get(0)得到旧值4- 执行
list.set(4, 4):你的方法把数组索引4的值改成4,返回新值4(而不是原本的3) - 接着执行
list.set(0, 4):把数组索引0的值设置为4(本来应该设置成刚才的旧值3)
此时数组变成[4,2,0,1,4]
- 第二次交换索引1和3:
list.get(1)得到旧值2- 执行
list.set(3, 2):你的方法把数组索引3的值改成2,返回新值2(而不是原本的1) - 接着执行
list.set(1, 2):把数组索引1的值设置为2(本来应该设置成刚才的旧值1)
最终数组就变成了[4,2,0,2,4],和你看到的异常结果完全一致!
修复方案
修改set方法,先保存旧值,赋值完成后返回旧值即可:
@Override public Integer set(int i, Integer e) { int oldValue = array[i]; array[i] = e; return oldValue; }
修复后再运行测试代码,Collections.reverse就能正常工作,数组和列表都会被正确反转为[3,1,0,2,4]。
内容的提问来源于stack exchange,提问作者user4910279
相关产品推荐
相关产品推荐

