2016-10-16 47 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是一个静态类,加上我现在不会涉及的其他更改,但我猜这个类目前是不完整的。