Java中ArrayList右旋转后返回结果与预期不符的原因解析
问题原因分析与解决方案
嘿,我来帮你拆解下这个问题的核心原因,其实是两次调用旋转方法+ArrayList的引用传递特性共同导致的差异:
1. 你调用了两次rotateArray方法
看你的main方法代码:
rotateArray(numbers, k); // 第一次调用,已经修改了原列表 ArrayList<Integer> ans = rotateArray(numbers, k); // 第二次调用,再次修改原列表
第一次调用rotateArray时,方法已经把原numbers列表向右旋转了3次,此时列表变成了[5, 6, 7, 1, 2, 3, 4]——这也是你在方法内部打印看到的预期结果。
但你没有接收这次调用的返回值,紧接着又调用了一次rotateArray,这时候原列表已经是旋转3次后的状态,再旋转3次,相当于总共旋转了6次。对于7个元素的列表来说,向右旋转6次等价于向左旋转1次,最终结果自然变成了[2, 3, 4, 5, 6, 7, 1]。
2. ArrayList是引用类型,方法内修改会直接影响原对象
你代码里的ArrayList<Integer> numbers1 = numbers;这行并没有创建新的列表,只是让numbers1指向了和原numbers相同的内存对象。所以方法内对列表的修改(添加、删除元素)都会直接作用于原列表,返回的也还是原列表的引用。
修复方案
这里给你两种常见的修复思路:
方案1:只调用一次旋转方法
直接移除多余的第一次调用,只保留一次调用就能得到预期结果:
public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); ArrayList<Integer> numbers = new ArrayList<>(); for (int i = 0; i < n; i++) { numbers.add(sc.nextInt()); } // 只调用一次旋转方法 ArrayList<Integer> ans = rotateArray(numbers, k); for (Integer x : ans) { System.out.print(x + " "); } }
方案2:方法内创建新列表,避免修改原对象
如果你希望原列表保持不变,或者不想担心重复调用的问题,可以在方法内部创建一个新的ArrayList进行操作,同时还可以优化旋转次数(当k大于列表长度时,取模减少循环次数):
static ArrayList<Integer> rotateArray(ArrayList<Integer> numbers, int k) { // 基于原列表创建新的列表,不修改原对象 ArrayList<Integer> numbers1 = new ArrayList<>(numbers); int n = numbers1.size(); // 计算有效旋转次数,避免不必要的循环(比如k=10和k=3效果一样,因为10%7=3) k = k % n; for (int i = 0; i < k; i++) { numbers1.add(0, numbers1.get(numbers1.size() - 1)); numbers1.remove(numbers1.size() - 1); } System.out.println("numbers: " + numbers1.toString()); return numbers1; }
内容的提问来源于stack exchange,提问作者Neel Chavan
相关产品推荐
相关产品推荐

