繁体   English   中英

如何使用变量创建对我的对象的引用?

[英]How do I create a reference to my object using a variable?

所以我有一个充满节点的数组,称为“ SNode s”(它们是我自己创建的一类。它们实际上只是一个包含单个字符串和指向下一个节点的指针的基本节点)。

我有一个名为insertValue()的方法,它接收您想要放入值的索引和您想要SNode包含的字符串。 但是,如果传递的索引中已经包含一个SNode ,我希望新值成为该SNode的“下一个”节点(本质上是在每个索引空间中创建一个节点链表)。

private int insertValue(int arrayPos, String element){//Checks for collisions with another SNode, and inserts the SNode into the appropriate spot in the array
 SNode targetNode = array[arrayPos];//What I want to be a reference to the node at the desired position in the array

 while (targetNode != null){//If an SNode already exists in that position, keeps iterating down until it gets to a non-existant SNode.
  targetNode = targetNode.getNext();//getNext is a method in my SNode that just returns a reference to that SNode's "nextNode" variable.
 }
  targetNode = new SNode(element);
  return arrayPos;
}//end insertValue

我的问题是,运行此方法后,它不会在所需的数组位置创建新节点,即使在数组点为空的第一次运行时也是如此。

如果我改变targetNode = new SNode(element); to array[arrayPos] = new SNode(element); 这显然插入SNode入阵就好了,这样使我相信所发生的事情是新SNode被变量下创建targetNode ,但targetNode它实例化后,没有连接到阵列的位置。 我假设它本质上是将数据从第 2 行的数组位置复制到变量中,但随后成为它自己的独立实体。

那么我如何让targetNode实际引用并影响SNode呢? 这样,当我遍历已占用数组空间中的节点链表时,targetNode 指向正确的节点。

注意:为了简单起见,我已经离开了使用上的行setNext()方法SNode前一节点的链接列表中的链接到它的下一个。

这里targetNode指的是array[arrayPos]引用的对象。

 SNode targetNode = array[arrayPos];//What I want to be a reference to the node at the desired position in the array

但是当你写:

targetNode = targetNode.getNext();//getNext is a method in my SNode that just 

您更改targetNode变量引用的对象。 现在它指的是它的下一个节点。

然后当你这样做时:

 targetNode = new SNode(element);

您创建一个新对象并将其分配给targetNode变量,但最终它永远不会关联到现有节点。

它不会为下一个节点分配一个新节点。
要做到这一点,你可以写:

targetNode.setNext(new SNode(element));

你有一个误解。 变量和数组元素都不保存对象。 它们持有对对象的引用 此外,变量和数组位置本身不是对象,因此在 Java 中无法引用它们。 您能得到的最接近的是拥有变量或数组位置包含的值的副本(对对象的引用)。

于是,这...

SNode targetNode = array[arrayPos];

... 将array[arrayPos]的值复制到变量targetNode 如果该值非null则变量随后引用与数组元素相同的对象,但不会复制对象本身。 这很好,在那种情况下正是你想要的,因为当你用

targetNode = targetNode.getNext();

,您不想修改array[arrayPos]或任何节点的next引用,因为那样您将丢失链表的元素。

但你不能同时拥有它。 当您最终找到新SNode的位置并执行此操作时...

targetNode = new SNode(element);

...它不会记录对新SNode的引用,无论您最近从哪里复制targetNode的值。 它只是将引用放在targetNode

你想要做的是找到最后一个当前节点,如果有的话,并分配给它的next引用(或者直接分配给数组元素,如果它最初是null )。

正如其他答案所示,使用正常的解决方案,您将测试它是否是数组中的第一个元素,并在这种情况下做一些不同的事情。 也就是说,如果是第一个,则直接在数组中设置元素,如果不是,则遍历列表。

一种有效的替代方法是在数组中使用一个虚拟元素,该元素仅用于其下一个字段,并在创建时使用虚拟元素初始化数组。 在你的情况下,你甚至可以给虚拟元素一个额外的last字段,这将不需要遍历列表来找到最后一个元素。 类似于以下内容:

interface SNodeRef {
    SNode getNext();
    void setNext(SNode node);
}

class FirstNode implements SNodeRef {
    SNodeRef getLast();
    void setLast(SNodeRef);
    ....
    FirstNode() { setLast(this); }
}

class SNode implements SNodeRef { ... }

private int insertValue(int arrayPos, String element) {
    SNode newNode = new SNode(element);
    FirstNodeRef ref = array[arrayPos];
    ref.getLast().setNext(newNode);
    ref.setLast(newNode);
}

FirstNode[] array = new FirstNode[10];
for (int i = 0; i < array.length; i++) {
    array[i] = new FirstNode();
}

或者,由于它是您正在使用的LinkedList ,您可以简单地使用预定义的LinkedList数据结构:

private int insertValue(int arrayPos, String element) {
    array[arrayPos].addLast(element);
}

var array = new LinkedList<String>[10];
for (int i = 0; i < array.length; i++) {
    array[i] = new LinkedList<String>();
}

暂无
暂无

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

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