有人能告诉我为什么A也改变了吗?

时间:2018-06-17 21:12:48

标签: java

返回一个列表,其中包含A的元素,后跟B的元素。不能修改A的项目。使用'new'。 IntList看起来像这样。

public class IntList { 
    public int first;
    public IntList rest;

    public IntList(int first, IntList rest) {
        this.first = first;
        this.rest = rest;
    }
}

public static IntList catenate(IntList A, IntList B) {
    //TODO:  fill in method
    IntList C = new IntList(A.first, A.rest);
    IntList L = C;
    while(L.rest != null) {
        L = L.rest;
    }
    L.rest = B;
    return C;
}

我不知道为什么在最后,A也改为C. 以下是测试。

public void testCatenate() {
    IntList A = IntList.list(1, 2, 3);
    IntList B = IntList.list(4, 5, 6);
    IntList exp = IntList.list(1, 2, 3, 4, 5, 6);
    assertEquals(exp, IntList.catenate(A, B));
    assertEquals(IntList.list(1, 2, 3), A);
}

结果是

java.lang.AssertionError: 
Expected :(1, 2, 3)
Actual   :(1, 2, 3, 4, 5, 6)

2 个答案:

答案 0 :(得分:1)

在构造函数中,行

this.rest = rest;

使新列表中的rest引用与传入的完全相同的列表。这意味着在catenate的第一行之后,C.restA.rest是引用到完全相同的清单。

然后,涉及L和后续L.rest = B;的循环将B连接到C.rest的末尾。但由于此列表与A.rest相同,因此似乎B已与AC连接。

要解决此问题,请在构造函数中删除this.rest = rest;,并将其替换为实际复制rest中条目的代码。

答案 1 :(得分:1)

如果您不想修改IntList,请先填写字段并最后休息,这样一旦设置就无法更改。

catenate方法需要复制A,因此它不会修改原始列表。

要执行此操作,请按原样循环遍历列表,但在每个步骤中保存该值(在另一个IntList中或在另一个结构中,如ArrayList。然后,一旦获得最后一个值,创建一个新的IntList,首先作为A中的最后一个值,然后作为B。

new IntList(L.first, B);

现在循环浏览从A保存的项目,按相反顺序将它们添加到此新列表中。