【问题标题】:How a java class works with it's own reference typejava 类如何使用它自己的引用类型
【发布时间】:2015-07-03 14:13:21
【问题描述】:

我对 JAVA 和 OOP 还很陌生,目前我正在学习一门学术课程,学习 Java 中的数据结构和算法。

在学习链表的实现时,我遇到了一个小问题,即在实现链表时不了解如何创建节点的代码(我熟悉构造函数和一点递归)。

Node类的代码如下

public class Node {
    public int info;
    public Node next, prev;
    public Node (int el) {
        this (el,null,null);
    }
    public Node (int el,Node n,Node p){
    info = el; next =n; prev=p;
    }
}

我需要知道代码执行时幕后发生了什么(尤其是line3是如何工作的)List类的代码如下

public class List {
    private Node head, tail;
    public List ( ){
        head = tail = null;
    }
    public boolean isEmpty( ){
        return head == null;
    }
    public void addToTail (int el) {
        if (!isEmpty ( )) {
        tail = new Node (el, null, tail);
        tail.prev.next = tail;
        } 
        else head = tail = new Node(el);
    }
    public int removeFromTail ( ){
    int el = tail.info; 
        if (head == tail)
        head = tail =null;
        else 
        { 
        tail = tail.prev; tail.next = null; 
        } 
    return el; 
    } 
}

(这个例子是我正在学习的学院给出的,我想知道它是如何工作的)

请解释 Node 类 的工作原理。

【问题讨论】:

  • 您有什么具体问题吗?
  • 您可以使用调试器进行跟踪,并阅读“双向链表”。有很多很好的图表可以解释。
  • 您发布了 List 类的完整代码吗?有一个双向链表没有什么意义,然后只有 addToTail / removeFromTail 方法。似乎没有机制让您实际遍历列表。
  • 我了解链表一般如何工作的理论,但作为 java 的新手,我只是不清楚 Node 类是如何工作的(尤其是第 3 行的引用节点类)
  • @dave 不,这只是 List 类的一部分,我没有为 list 类添加整个代码以使其简短

标签: java class oop reference


【解决方案1】:

好的,让我们从Node 类开始

public Node next, prev;
    public Node (int el) {
        this (el,null,null);
    }

这里的对象nextprev 是对当前节点的下一个和上一个节点的引用(这是您当前的对象(this))

this (el,null,null);

这意味着您正在创建一个没有前一个或下一个节点的节点。当您传递 null 时,为下一个和上一个传递 null。它类似于创建一个头部,因为头部没有下一个和上一个节点。

当你创建头部时,你永远不会改变它,但是当你在列表中创建第二个元素时,你会改变头部的下一个

当你创建链表的尾部时

 public void addToTail (int el) {
        if (!isEmpty ( )) {
        tail = new Node (el, null, tail);
        tail.prev.next = tail;
        } 
        else head = tail = new Node(el);
    }

这里你首先通过tail = new Node (el, null, tail);创建一个尾节点 然后通过tail.prev.next = tail;获取tail的prev并将prev的下一个元素设置为tail。

每次向列表中添加一个新节点时,您都​​调用addToTail(int e1),它会更新尾部并更新旧尾部的下一个。

【讨论】:

    【解决方案2】:

    假设您的代码的入口点是调用:

    List list = new List();
    list.addToTail(1);
    list.addToTail(2);
    list.removeFromTail();
    

    第一行代码在list类中执行构造函数,简单地将head和tail设置为null。

    第二行代码添加方法addToTail,设置变量head和tail等于new Node(1),调用Node类中只有一个参数的构造函数。

    第三行代码添加方法addToTail,但这次列表不为空,所以脚本进入if语句和你用Node(2, null, tail)保存的节点。如果使用三个参数检查此 Node 构造函数,tail(您之前添加的值为 1 的节点)将被设置为与当前节点关联的 prev(上一个)节点。

    最后一行代码删除第二个节点,代码tail = tail.prev; tail.next = null;并返回您刚刚删除的元素。

    【讨论】:

      【解决方案3】:

      首先节点在java中它是一个特定类型的变量,它可以做一个变量的正常工作并有一个其他信息允许她指向另一个节点,在你的情况下是public Node next, prev;

      通常在列表中使用节点,想像火车这就是为什么你在这里有addtootailremovefromtail。 在此链接中,您可以找到一个非常详细的解释。 http://www.vias.org/javacourse/chap14_02.html

      【讨论】:

        【解决方案4】:

        Node 类封装了数据,在本例中是一个名为 info 的整数值。

        另外,List 被实现为Nodes 的序列。

        Node 中的nextprev 值的原因是该节点可以链接到列表序列中的前一个和下一个节点。访问列表中的节点的唯一方法是遍历列表,或者使用next 引用向前,或者使用prev 引用向后。

        请注意,列表不像数组那样支持随机访问。要到达某个元素,您需要沿某个方向遍历列表。

        【讨论】:

          【解决方案5】:

          我需要知道代码执行时幕后发生了什么(尤其是 line3 的工作方式)。

          请解释 Node 类的工作原理。

           public Node next, prev;
          

          引用对象类型的Java 变量是引用,而不是值。 nextprev 字段不是 Node 对象。没有Node 对象包含其他节点。相反,nextprev 引用了单独存储的 Node 对象。

          如果您来自 C 或 C++,您可以将这些引用视为有点像指针。

          编辑:

          如果您询问的是一般链表的构造,您的 Node 类表示双向链表中包含单个项目的单个节点。在双向链表中,每个节点指的是之前的节点和之后的节点。

          在这篇相关的维基百科文章中查看illustration of a doubly linked list

          List 就像一列火车。 Node 就像火车上的汽车。链接是节点之间的引用,类似于火车车厢之间的耦合。您询问的nextprev 字段是节点之间的链接。

          从逻辑上讲,列表包含整个火车。从物理上讲,您的 List 引用了火车的头部和尾部,因此它可以从前到后或从后到前穿过节点。

          【讨论】:

          • 不是真正的答案,只是对他们没有提出的几点进行更正。
          • @Andy Thomas tbh 这并不能回答 OP 过于宽泛的问题
          • @weston - OP 专门询问了第 3 行,Java 初学者最常见的误解是引用变量是对象的概念。我认为这很可能解决了 OP 困惑的根源。但是,正如您所指出的,它足够宽泛,我可能会弄错。所以,让我扩大答案。
          猜你喜欢
          • 1970-01-01
          • 2011-02-05
          • 2016-06-03
          • 2010-10-24
          • 2021-08-31
          • 1970-01-01
          • 2017-07-10
          • 2018-10-07
          • 2020-01-14
          相关资源
          最近更新 更多