【问题标题】:Java - Custom iterator not able to track head of custom linked listJava - 自定义迭代器无法跟踪自定义链表的头部
【发布时间】:2016-07-10 08:04:35
【问题描述】:

课程不完整,但这是我目前所掌握的,我希望下面的测试能够通过。

public class LinkedList<T> extends AbstractSequentialList<T> {
  private Node<T> head;

  @Override
  public boolean add(T element) {
    if(head == null) {
      head = new Node(element);
    }
    return true;
  }

  @Override
  public ListIterator<T> listIterator(int index) {
    return new LinkedListIterator<>();
  }

  @Override
  public int size() {
    return 0;
  }

  private class LinkedListIterator<T> implements ListIterator<T> {
    private Node<T> current;

    public LinkedListIterator() {
        current = (Node<T>) head;
    }

    @Override
    public boolean hasNext() {
        return (current != null && current.getNext() != null)? true : false;
    }

    @Override
    public T next() {
        return null;
    }
  }
}

这里是 Node 类。

public class Node<T> {

  private T value;
  private Node next;

  public Node(T value) {
    this.value = value;
  }

  public Node(T value, Node next) {
    this.value = value;
    this.next = next;
  }

  public T getValue() {
    return value;
  }

  public Node getNext() {
      return next;
  }

  public void setNext(Node next) {
      this.next = next;
  }
}

我的迭代器测试是这样的。

LinkedList<String> list;
ListIterator<String> iterator;

@Before
public void setUp() throws Exception {
    list = new LinkedList<>();
    iterator = list.listIterator();
}

@Test
public void testHasNext() throws Exception {
    assertThat(iterator.hasNext(), is(false));

    list.add("Hello World");
    assertThat(iterator.hasNext(), is(true));
}

但是,我在第二个断言上失败了。我的问题是迭代器中的“当前”指针始终为空,即使我将它设置为封闭 LinkedList 类的头部。我怎样才能解决这个问题?谢谢。

【问题讨论】:

  • getNext() 总是返回 null 所以 (current != null && current.getNext() != null) 总是 false
  • @JEY 用 Node 类的代码更新了帖子。调试时,我实际上看到当前为空。在调用 getNext() 之前条件已经失败。

标签: java linked-list iterator


【解决方案1】:

看起来 current 的值是在 LinkedListIterator 的构造函数中设置的。

在您将元素添加到列表后,它尚未更新。这似乎是您的问题。

【讨论】:

  • 根据我的经验,我不希望迭代器在所有情况下都反映对底层数据结构的更改。我总是通过文档检查具体的实现;如果通过源代码没有提到任何内容,并且如果我没有源代码,我会设置一个快速测试来确定。
【解决方案2】:

IMO,您的测试有问题。

如果在构造迭代器之后添加了第一个元素,则不应期望迭代器指向第一个元素。

现在,为什么您的迭代器会这样工作?因为Java是按值传递的。当您构造一个迭代器时,迭代器会接收到对列表第一个节点的引用的副本。而此时这个引用是空的,因为你还没有添加任何节点。

如果你真的想让迭代器“看到”列表的第一个节点,即使它已经被构造了,那么迭代器需要在hasNext()中获取列表的第一个节点,而不是在构造函数中。

【讨论】:

    猜你喜欢
    • 2021-02-27
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 2013-02-17
    • 1970-01-01
    相关资源
    最近更新 更多