在两个数组中交换值时出现无法解释的问题

3

你好,我一直在努力解决程序中的错误,已经花了好几个小时了,但还是找不到问题所在。我不想在这里解释我的程序应该做什么,因为我已经尽可能地用较少的代码重新制作了它来复制这个bug,这段代码只是交换了两个数组的值,为了简单起见,我让这两个数组只包含一个值,array1的值为1,array2的值为2。

每当“BUGGED”注释行被激活而不是上面那行时,输出如下所示:

交换前: 第一个值:[1] 第二个值:[2] 交换后: 第一个值:[2] 第二个值:[2]

如果使用第一行,则输出正确(交换后:2 1)。

我应该补充说明,如果我创建多个数组(任意数量),则该错误仅出现在第一个和最后一个值。

例如,如果我创建4个值分别为1、2、3和4的数组并尝试进行交换,则只有第一个和最后一个数组的值会发生变化。

temp < 1 < 2 < 3 < 4 < temp 

我将在最后遇到这种情况:2、3、4、2。

以下是主类的代码。

class Testing {

int[] one = {1};
int[] two = {2};

TestingArray array1 = new TestingArray(one);
TestingArray array2 = new TestingArray(two);

public static void main(String[] args) {

    Testing test = new Testing();

    System.out.println("Before swap:");
    System.out.println("First value: "+Arrays.toString(test.getArray1()));
    System.out.println("Second value: "+Arrays.toString(test.getArray2()));

    test.swap();

    System.out.println("After swap:");
    System.out.println("First value: "+Arrays.toString(test.getArray1()));
    System.out.println("Second value: "+Arrays.toString(test.getArray2()));

}

int[] getArray1() {
    return array1.getArray();
}

int[] getArray2() {
    return array2.getArray();
}
void swap() {

    int[] temp = array1.getArray();
    array1.setArray(array2.getArray());
    array2.setArray(temp);
}

}

这是第二个类。

public class TestingArray {

private int[] array = new int[1];

TestingArray (int[] value) {

    this.array = value;
}

int[] getArray() {
    return array;
}

void setArray(int[] array) {
    this.array = array;
//      this.array[0] = array[0]; // BUGGED 
}
}

非常期待你的回答,我真的很迷茫。


这段代码运行正常,当我运行时,在交换后我得到了 [2], [1],问题出在哪里? - Maljam
@Maljam,关键是现在它可以工作,但如果他使用注释语句,则无法正常工作。他想知道为什么注释语句不能按预期工作。 - 4castle
记得清楚地陈述问题。确保我们的用户清楚地知道出了什么问题。最好说“当我调用swap(1,2)时,没有值发生变化”,或者类似的话,而不是说“它不起作用,我迷失了方向”。同时也要谈论任何错误信息。 - Matt C
@MatthewCliatt 我认为问题很清楚,只是人们没有注意到而只是复制了代码。我也做了完全相同的事情,直到我记起了问题。 - 4castle
1个回答

2
问题出现在 swap() 方法中,你的 temp 变量是 array1 的一个引用而不是一个副本,如果你想改变数组中的值,temp 变量应该是一个副本。
void swap() {//e.g. arr1 → {1}, arr2 → {2}
    int[] temp = array1.getArray(); //arr1 → {1} ← temp, arr2 → {2}
    array1.setArray(array2.getArray()); //arr1 → {2} ← temp, arr2 → {2}
    array2.setArray(temp); //arr1 → {2} ← temp, arr2 → {2} / no change
}

正如你所看到的,当你调用 array1.setArray(array2.getArray()) 时,你也改变了 temp 的值,因为它们引用同一个数组。

你应该这样做:

void swap() {
    int[] temp = Arrays.copyOf(array1.getArray(), array1.getArray().length); //arr1 → {1}, temp → {1}, arr2 → {2}
    array1.setArray(array2.getArray()); //arr1 → {2}, temp → {1}, arr2 → {2}
    array2.setArray(temp); //arr1 → {2}, temp → {1}, arr2 → {1}
}

您可以阅读有关Java引用变量与基本变量的更多信息。

非常感谢,这是我第一次遇到一个问题卡了这么久,不得不在某个地方发帖求助。我刚开始学习Java和编程,所以这个问题真的让我很困惑。如果您能解释一下为什么第一行代码可以工作而第二行不能,无论如何再次感谢! - Daniel
我花了一些时间才明白为什么这是解决方案。这是因为当你只做一个引用复制时,任何对array1的修改也将成为temp的修改,这会破坏对array2的后续修改,因为它使用新的array1值而不是旧的array1值。(我感到有点晕) - 4castle
@Daniel 我添加了更多的解释,希望有所帮助。 - Maljam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接