简体   繁体   English

链接列表示例中“this”指的是什么?

[英]What does “this” refer to in Linked List example?

So I'm skimming through Cracking the Coding Interview to brush up on some interview stuff and I ran across this linked list implementation, and maybe it's been a while but it's completely going over my head. 因此,我正在通过Cracking the Coding Interview来浏览一些采访内容并且我遇到了这个链接列表实现,也许它已经有一段时间了,但它完全超出了我的想象。 I understand most of it, except for one specific line, and it's throwing me off. 我理解其中的大部分,除了一条特定的线,它让我失望。 I'll post the code below (for reference, the book doesn't mention language but it appears to be Java.) 我将在下面发布代码(供参考,本书不提及语言,但它似乎是Java。)

class Node {
    Node next  = null;
    int data;

    public Node(int d) {
        data = d;
    }

    void appendToTail(int d) {
        Node end = new Node(d);
        Node n = this;
        while(n.next != null) {
            n = n.next;
        }
        n.next = end;
    }
}

I'm a little confused on the line: Node n = this - I'm not sure what this is referring to, unless it's talking about next - why not just set it to null in that case? 我有点困惑: Node n = this - 我不确定this是指什么,除非它在谈论next - 为什么不在这种情况下将它设置为null

This is Java. 这是Java。

" this " refers to the specific instance of the class in which the call is being made. this ”指的是进行调用的类的特定实例。 In this case, " this " is in reference to the specific class Node you are dealing with. 在这种情况下,“ this ”是指您正在处理的特定类Node While the variable " end " creates a new and separate version of the Node class which is constructed using the passed int " d ". 变量“ end ”创建一个新的独立版本的Node类,它使用传递的int“ d ”构造。

this refers to a specific instance of an object of a class. this指的是类对象的特定实例。 Since objects are constructed there can be multiple instances of a class, but using the this keyword allows you to obtain a reference to itself, meaning a reference to the the specific instance of the object whose method is being called. 由于构造了对象,因此可以有多个类的实例,但使用this关键字可以获得对自身的引用,这意味着对正在调用其方法的对象的特定实例的引用。

The linked list is a collection of nodes that are, well, linked together. 链表是一组链接在一起的节点。 When you call appendToTail() the node will look at all of the Node objects linked to itself and follow the chain. 当您调用appendToTail()该节点将查看链接到自身的所有Node对象并跟随链。 For it to get a reference to itself to follow its own chain the this keyword is used. 为了获得对自身的引用以跟随其自己的链,使用this关键字。

You also ask why null isn't used in this case to initialize n . 您还要问为什么在这种情况下不使用null来初始化n This would cause a NullPointerException when n.next is first called in the loop constraint, so instead its own reference is used as the starting point for the iteration of the linked-list. 当在循环约束中首次调用n.next时,这将导致NullPointerException ,因此将其自己的引用用作链表的迭代的起始点。

This (pun intended) can be a confusing topic at first, but lets use the example you provided. 这个(双关语)起初可能是一个令人困惑的话题,但让我们使用您提供的示例。

Node n = this;
while(n.next != null) {
    n = n.next;
}

Let's pretend that there are 4 objects currently linked in our list and for simplicity's sake the Node object that appendToTail() is being called on is the head of the list. 让我们假设我们的列表中当前链接了4个对象,为简单起见,调用appendToTail()的Node对象是列表的头部。 Here's the reference value of Node n that's held on each loop iteration from the above snippet. 这是节点n的参考值,它是在上面代码片段的每次循环迭代中保留的。

  1. We're pointing to ourself - this 我们指着自己 - this
  2. Pointing to the second item in the linked list. 指向链表中的第二个项目。 - this.next - this.next
  3. Pointing to the following item - this.next.next 指向以下项目 - this.next.next
  4. Pointing to the last item in the list - this.next.next.next 指向列表中的最后一项 - this.next.next.next

The loop ended so currently the reference of n = this.next.next.next . 循环结束当前n = this.next.next.next的引用。 We then set n 's next value (where n is currently pointing to the end of the linked chain) to the new object we created at the beginning of our method, which makes it the new end of the list. 然后我们将n的下一个值(其中n当前指向链接链的末尾)设置为我们在方法开头创建的新对象,这使它成为列表的新结尾。 ( n.next = end is now equivalent to this.next.next.next.next = end ). n.next = end现在相当于this.next.next.next.next = end )。

Semi-Unnecessary Edit: This is explained in terms of Java. 半不必要的编辑:这是用Java来解释的。 It appears that someone added the C++ tag after I wrote this answer 在我写完这个答案之后,似乎有人添加了C ++标签

Since this is a Linked List all Nodes are connected and you have a start Node (root). 由于这是一个链接列表,所有节点都已连接,并且您有一个启动节点(根)。 So when using it it would look like this: 所以当使用它时,它看起来像这样:

Node root = new Node(6); //need an instance first
root.appendToTail(5);
root.appendToTail(3);
//6->5->3

Since this the nodes are connected I need one start Node and need to check if this has a next node when yes I need to search deeper. 由于节点已连接,我需要一个启动节点,需要检查是否有下一个节点,我需要更深入地搜索。 When a node did not have a next Node it is the current last one and can add my new Node. 当一个节点没有下一个节点时,它是当前最后一个节点并且可以添加我的新节点。 So this in Java refers to the current instance of a class. 所以这在Java中引用了类的当前实例。 In my example the root Node(because I call root.appendToTail). 在我的例子中是根节点 (因为我称之为root.appendToTail)。 So the method will search from the root Node (value 6) the next Node without a next Node (the one with value 3) and append it there. 因此,该方法将从根节点 (值6)搜索下一个节点而没有下一个节点(值为3的节点)并将其附加到那里。 If I can get a child reference and would call child3.appendToTail the method would search from child3 instead of starting from my root. 如果我可以获得子引用并调用child3.appendToTail,则该方法将从child3搜索而不是从我的root开始。

When setting n to null and rewriting the while to go from this.next you would have a problem when the current node you use appendToTail did not have a next Node and an NullPointerException would be thrown. 当将n设置为null并从this.next重写while时,如果使用appendToTail的当前节点没有下一个Node并且将抛出NullPointerException,则会出现问题。

Node n = this; means n object references to the object which is calling this method. 表示对象调用此方法的对象引用。 So method is looping to next object till next object is null and assigning end node to the end. 因此,方法循环到下一个对象,直到下一个对象为空并将end节点分配给结尾。

Lets see 让我们来看看

1 -- 2 -- 3 -- 4
*
|
*
obj

you have an obj object that is pointing to node 1. When u call obj.appendToTail(5) 你有一个指向节点1的obj对象。当你调用obj.appendToTail(5)

Node end = new Node(d); //new node is created to add to the end.
Node n = this; //local n object is referenced to node 1(or obj)
while(n.next != null) {
   n = n.next;
}
//n here is node 4 since there is no next node to 4
n.next = end; //node 5 is tail now

End result: 1 -- 2 -- 3 -- 4 -- 5 最终结果: 1 -- 2 -- 3 -- 4 -- 5

Any Node instance can call appendToTail() . 任何Node实例都可以调用appendToTail()

Notice howebet, here in fact Node does not append itself to tail of the list, what happens here is that new node is created and added to tail, not the one on which method is invoked. 注意howebet,这里其实Node本身添加到列表的尾部,这里所发生的是,新节点被创建并添加到尾,而不是一个在其上调用的方法。

For this to happen, first we need to find the tail of the list given the current Node . 为此,首先我们需要在给定当前Node找到列表的尾部。

  // n is pointing to current Node
  while(n.next != null) {
            n = n.next;
        }

Once we find node which has next == null, this is tail of the list so we can now append new Node to the tail: 一旦我们找到具有next == null的节点,这就是列表的尾部,所以我们现在可以将新Node添加到尾部:

    // n points to current tail before next line is invoked
    n.next = end;

As to why there is line: 至于为什么有线:

    Node n = this;

Well since there is no LinkedList class which maintains reference to the head, you have to be able to iterate from any given Node. 好吧,因为没有LinkedList类来维护对头部的引用,所以你必须能够从任何给定的Node迭代。 That is what happens here, you start iteration from Node on which appendToTail is called, but that Node can be anything at this point, from head to tail. 这就是这里发生的事情,你从调用了appendToTail Node开始迭代,但是从那个头到尾,那个节点可以是任何东西。

As a side note, if you implement Linked List by hand, make sure to actually have class LinkedList which will offer methods such as add , get , size , appendToTail and so on, rather then putting these into Node class. 作为旁注,如果你手动实现Linked List,请确保实际上有类LinkedList,它将提供addgetsizeappendToTail等方法,而不是将它们放入Node类。

As you can see in this code 正如您在此代码中看到的那样

class Node {
   //

   void appendToTail( int d ) {
       Node *end = new Node( d );
       Node n = this;
       // ...
   }
}  

Your class Node has a reference to a Node in it's definition. 您的类Node在其定义中引用了Node

The line: Node *end = new Node( d ); 行: Node *end = new Node( d ); means inside a Node there is a reference to another node. 表示在Node内部有一个对另一个节点的引用。

The line Node n = this; 线Node n = this; means inside a Node the reference to that node itself , is represented by this . Node内部表示对该节点本身的引用, this表示。 Ergo, n is also a reference to said node itself. Ergo, n也是对节点本身的引用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM