我在java中进行了一些实验并偶然发现了这个问题
假设我有一个具有此递归定义的类
public class Node<T> implements Iterable<T>{
public final T element;
public final Node<T> next;
public Node(T head, Node<T> tail) {
this.element = head;
this.next = tail;
}
// Contains few more methods and implementation of iteratable like add, remove etc
}
现在,我将使用此类作为具有final关键字的另一个类中的字段。现在,如果在开始时我将创建一个空列表,然后将其添加到列表中,我应该如何继续。
简化
class NodeList <T>{
private final Node<T> head;
public NodeList(){
}
// Few more functions
}
使用NodeList类如何创建一个空列表,然后使用添加函数
添加数据答案 0 :(得分:2)
在java 引用中作为指向内存中对象的指针,内部可以以相同的方式指向另一个对象。
让我们尝试在视觉上理解 :
当对象obj被添加到空链表时,指针头会发生什么?
您必须从final
中删除head
关键字,因为每次添加新节点以指向新节点时,该引用都会更改。
在下面的快照中,head
是指向内存中第一个对象的引用,第一个对象包含指向第二个对象的另一个引用next
,依此类推......
我应该怎样继续。
next
指向头部的next
head
指向新节点示例代码:
class Node<T> {
public final T element;
public final Node<T> next;
public Node(T head, Node<T> tail) {
this.element = head;
this.next = tail;
}
}
class NodeList<T> {
private Node<T> head;
public void add(T value) {
if (head != null) {
Node<T> node = new Node<T>(value, head); // create a new node
head = node; // point `head` to new node
} else {
// if head is null then assign it to head
head = new Node<T>(value, null);
}
}
}
NodeList<String> nodeList = new NodeList<String>();
nodeList.add("First");
nodeList.add("Second");
nodeList.add("Third");
// print all nodes
Node<String> node = nodeList.head;
while (node != null) {
System.out.println(node.element);
node = node.next;
}
输出:
Third
Second
First
答案 1 :(得分:0)
你不能在head属性上使用final关键字,因为它会强制你在instanciation期间初始化它:你应该将它初始化为null以表示空列表,并且无法附加元素它。删除final关键字,它在那里没用。
我甚至不相信在你的Node类中使用final。如果要添加或删除列表中间的元素,该怎么办?使用final可以极大地限制您可以对数据结构执行的操作数量。