2016-10-16 49 views
-1

我正在用Java編寫一個Bag的簡單實現。我正在執行Iterable並編寫我自己的LinkedList迭代器。所以我在絞盡腦汁;我正在嘗試向鏈接列表添加元素。我有一個工作實現(add()函數中註釋掉的代碼)。不過,我不明白爲什麼下面的代碼不工作:Java中的單鏈表實現Iterator

current.item = item; 
Node<T> nextNode = new Node<T>(); 
current.next = nextNode; 
current = nextNode; 

因此,考慮該列表是空的,當前的頭部被初始化,但沒有項目或未來:我分配項目到當前項目,創建一個新節點,將其設置爲當前的下一個並將當前(頭)更改爲剛剛創建的節點。添加兩個項目的名單,我打印出來的對象爲後人:

電流:袋$節點@ 4524411f未來:袋$節點@ 401e7803

電流:袋$節點@ 401e7803未來:袋$ @節點10dba097

電流:袋$ @節點旁邊10dba097:袋$ @節點1786f9d5

電流:袋$ @節點1786f9d5下一個:包$ @節點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() { 

     } 
    } 
} 
+0

此外,而不是downvoting的帖子(超棒的舉動)也許提供一些解釋 – nbpeth

回答

1

項目值不會丟失。問題是你失去了鏈接列表的頭部。您的current變量記錄了尾部,並且由於您的toArray()方法從current開始,所以while循環從不執行,因爲在列表的尾部元素之後沒有任何元素。

因此,您最終得到一組默認初始化的Object值,即null

要解決這個問題,您需要另一個實例變量來跟蹤列表頭,這就是您將在toArray()方法中使用的方法。

+0

極其簡單,幾乎足以想要刪除帖子。謝謝你 - 我的頭腦會在列表的簡單邏輯上爆炸,想知道我可能會錯過什麼。 – nbpeth

1

從我所看到的,它不充當鏈接列表的原因是因爲你沒有保留對第一個元素的引用。而是保留對最後(current)元素的引用。

您可以通過添加一個類別字段解析此引用的第一個元素在你的add()方法添加 T head

然後,設置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是一個靜態類,加上我現在不會涉及的其他更改,但我猜這個類目前是不完整的。