将“this”分配给Java中的引用变量

fet 发布于 2019-10-09 java 最后更新 2019-10-09 22:59 11 浏览

我试图用递归方法来完成单链表中的addLast方法,但是,该代码给了我一个list.size()= 2和list.getFirst()= 5的错误输出。原因应该是到线

SLList p=this;
看来改变p参考也会改变“这个”参考,这对我来说并不那么逻辑。任何人都可以提供一些关于此的细节?谢谢
public class SLList {
public class IntNode {
    public int item;
    public IntNode next;
    public IntNode(int i, IntNode n) {
        item = i;
        next = n;
    }
}
private IntNode first;
public SLList(int x) {
    first = new IntNode(x, null);
}
/** Adds an item to the front of the list. */
public void addFirst(int x) {
    first = new IntNode(x, first);
}
/** Retrieves the front item from the list. */
public int getFirst() {
    return first.item;
}
/** Adds an item to the end of the list. */
public void addLast(int x) {
SLList p = this;
    if (p.first. next == null) {
        p.first.next = new IntNode (x, null);
    }
else {
        p.first = p.first.next;
        p.addLast(x);
    }
}
/** Returns the number of items in the list using recursion. */
public int size() {
    /* Your Code Here! */
    SLList p = this;
    if (p.first == null) {
        return 0;
    }
    else if (p.first.next == null){
        return 1;
    }
else {
        p.first = p.first.next;
        return 1 + p.size();
    }
}
public static void main (String[] args) {
    SLList list=new SLList (5);
    list.addFirst(10);
    list.addFirst(15);
    list.addLast(17);
    System.out.println(list.getFirst());
    System.out.println(list.size());
}
}
已邀请:

dsit

赞同来自:

问题与this的分配无关。没有什么可以改变this。期。 (但事情可以改变this引用的对象的状态。) 真正的问题在于您实施size方法。您的size方法导致列表更改。它不应该。在您的情况下,更改会导致:

  • size()方法返回错误的值
  • 后续的getFirst()调用返回错误的值。
我不会确切地说出错误的位置,但你应该能够通过消除过程自己发现它。 (或者,如果失败,请使用调试器并尝试观察列表的更改位置。)

wsint

赞同来自:

您的算法存在比您想象的更大的问题。 size()不正确。如果您意识到需要计算列表中IntNode对象的数量,则可以解决此问题。同样,所有其他方法都需要操作IntNode对象。

snihil

赞同来自:

SLList p = this;
p引用相同的SLList对象。如果您对'p'进行任何更改,那么它也会发生'this',因为引用类型(不是值类型)。 在声明中
p.first = p.first.next;
当您调用'addLast'方法时,会更改对第一个的引用。您丢失了对第一个项目的引用。 如果删除该行
list.addLast(17);
在main方法中,您将看到正确的答案。问题在于这种方法。 更改方法如下,并在下面添加新方法。
/** Adds an item to the end of the list. */
public void addLast(int x) {
    addLast(x, this.first);
}
private void addLast(int x, IntNode node){
    if(node.next == null){
        node.next = new IntNode (x, null);
    }else {
        node = node.next;
        addLast(x, node);
    }
}
然后你不会丢失对第一项的引用,现在它工作正常,

qnon

赞同来自:

您的实现中的问题是addLast和size方法首先更改字段变量的值。 将this分配给某个变量或直接使用无关紧要。 因为将this分配给某个变量不会创建新的this对象,而是分配对该变量的引用。 所以你应该首先将first字段变量的值复制到某个局部变量然后迭代它。这样你的first就不会改变。 提示:不要更改第一个变量引用。 您的addLast()size()更改了first的值,这是错误的。 问题出在这一行。     p.first = p.first.next;