二维数组行移位填零功能异常:移位后非目标行被置零
二维数组行移位时引用赋值导致的错误分析与修复
问题原因
你代码里的第一个循环用了引用赋值:a[i] = a[i - shift];,在Java中数组是对象,直接给数组变量赋值只是让两个变量指向同一个数组对象,并没有复制数组的实际内容。
拿你的示例(shift=2,数组长度5)来说:
- 循环执行
i=4时,a[4] = a[2]→a[4]和a[2]指向同一个数组(原第三行[1,6,2,1,4]) - 执行
i=3时,a[3] = a[1]→a[3]和a[1]指向同一个数组(原第二行[1,1,3,1,1]) - 执行
i=2时,a[2] = a[0]→a[2]和a[0]指向同一个数组(原第一行[1,1,1,1,1])
当第二个循环把a[0]和a[1]的元素全置为0时,因为a[2]和a[0]是同一个数组对象,a[3]和a[1]也是同一个数组对象,所以a[2]、a[3]的元素也会被同步置0,这就导致了不符合预期的输出。
修复方案
需要复制数组的内容而非直接赋值引用,可用Arrays.copyOf()或System.arraycopy()实现:
修改后的完整代码
import java.util.Arrays; public class ArrayShift { public static void main(String args[]) { int[][] a = { { 1, 1, 1, 1, 1 }, { 1, 1, 3, 1, 1 }, { 1, 6, 2, 1, 4 }, { 1, 1, 1, 8, 1 }, { 1, 1, 1, 1, 1 } }; System.out.println(Arrays.deepToString(move(a, 2))); } public static int[][] move(int[][] a, int shift) { // 复制行内容,避免引用共享 for (int i = a.length - 1; i >= shift; i--) { a[i] = Arrays.copyOf(a[i - shift], a[i - shift].length); // 也可以用System.arraycopy,性能更优: // System.arraycopy(a[i - shift], 0, a[i], 0, a[i].length); } // 填充前shift行为0 for (int i = 0; i < shift; i++) { Arrays.fill(a[i], 0); } return a; } }
验证结果
修改后运行代码,输出为:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 1, 1, 1, 1], [1, 1, 3, 1, 1], [1, 6, 2, 1, 4]]
完全符合预期效果。
额外说明
Arrays.copyOf()会创建新数组并复制原数组元素,彻底避免引用共享问题。- 如果不想修改原数组,可以先创建一个新的二维数组,再完成移位和填充操作,原数组会保持不变。
内容的提问来源于stack exchange,提问作者Pengo
相关产品推荐
相关产品推荐

