[英]Singly Linked List implementation in Java Iterator
我正在用Java寫一個Bag的簡單實現。 我正在實現Iterable
並編寫自己的LinkedList
Iterator。 所以我在絞盡腦汁。 我正在嘗試將元素添加到鏈接列表。 我有一個可行的實現( add()
函數中注釋掉的代碼)。 但是,我不明白為什么以下代碼不起作用:
current.item = item;
Node<T> nextNode = new Node<T>();
current.next = nextNode;
current = nextNode;
因此,鑒於列表為空且當前頭已初始化但沒有項目或下一個項目:我將項目分配給當前項目,創建一個新節點,將其設置為當前項目的下一個節點,並將當前(頭)更改為該節點我剛創建。 將兩個項目添加到列表中,我打印出了后代對象:
當前:Bag $ Node @ 4524411f下一個: Bag $ Node @ 401e7803
當前: Bag $ Node @ 401e7803下一個:Bag $ Node @ 10dba097
當前:Bag $ Node @ 10dba097下一個: Bag $ Node @ 1786f9d5
當前: Bag $ Node @ 1786f9d5下一個:Bag $ Node @ 704d6e83
至少對我而言,很明顯,每次都很好地設置下一個新節點。 我將所有四個元素添加到包中,但是該項目丟失了,並且每個索引返回null。 toArray()函數顯示[null, null, null, null]
我敢肯定這很簡單。 以下是整個實現。
import java.util.Iterator;
public class Bag<T> implements Iterable<T> {
private Node current;
//Node<T> head;
private int numberofProducts;
T[] myBag;
int defaultCapacity;
public Iterator<T> iterator() {
return new ListIterator<T>(current);
}
public Bag(int defaultCapacity) {
this.current = new Node<T>();
this.numberofProducts = 0;
this.defaultCapacity = defaultCapacity;
}
public void add(T item) {
if(isFull()) {
System.out.println("bags full, yo");
return;
}
current.item = item;
Node<T> nextNode = new Node<T>();
current.next = nextNode;
current = nextNode;
numberofProducts++;
//Node<T> nextNode = current;
//current = new Node<T>();
//current.item = item;
//current.next = nextNode;
//numberofProducts++;
}
public Object[] toArray() {
Object[] array = new Object[size()];
int i = 0;
Node<T> node = current;
//Node<T> node = head;
while(node.next != null) {
array[i] = node.item;
node = node.next;
i++;
}
return array;
}
public boolean isEmpty() {
return this.numberofProducts <= 0;
}
public boolean isFull() {
return this.numberofProducts >= defaultCapacity;
}
public int size() {
return this.numberofProducts;
}
private class Node<T> {
private T item;
private Node<T> next;
}
private class ListIterator<T> implements Iterator<T> {
private Node<T> current;
public ListIterator(Node<T> first) {
current = first;
}
public boolean hasNext() {
return current != null;
}
public T next() {
if(hasNext()) {
T item = current.item;
current = current.next;
return item;
}
return null;
}
public void remove() {
}
}
}
項目值不會丟失。 問題在於您無法跟蹤鏈接列表的標題。 您的current
變量已經在跟蹤尾部,並且由於toArray()
方法從current
開始,因此while
循環永遠不會執行,因為列表的tail元素之后沒有任何元素。
因此,您僅得到一個默認初始化的Object
值數組,即null
。
要解決此問題,您需要另一個實例變量來跟蹤列表的開頭,這就是您將在toArray()
方法中使用的變量。
據我所知,它不充當鏈接列表的原因是因為您沒有保留對添加的第一個元素的引用。 而是保留對添加的最后一個( current
)元素的引用。
您可以通過在第一個元素中添加T head
添加類字段引用來解決此問題
然后在add()
方法中,將head
設置為您創建的Node
。 然后,在構造ListIterator時,將head
作為參數傳遞。
您可以將add(T item)
更改為如下所示:
public void add(T item) {
if (!isFull()) {
Node<T> toAdd = new Node<>();
toAdd.item = item;
current.next = toAdd;
current = toAdd;
if (head == null) {
head = toAdd;
}
}
}
然后將類字段Node<T> head
到Bag<T>
類中。
另外,我不確定為什么Node
是一個靜態類,以及我現在不打算進行的其他許多更改,但是我想該類目前還不完整。
問題出在用add()
方法編寫的邏輯上。 每當將新數據添加到Bag時,您的根節點都會更改,並指向Bag的最后一個節點。 由於倒數第二個節點為null,因此迭代器不返回任何內容。 請參考此鏈接以獲取確切的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.