【问题标题】:Correct implementation of List Iterator methodsList Iterator 方法的正确实现
【发布时间】:2016-05-24 03:15:44
【问题描述】:

为了更好地了解迭代器,我将自己编写它们以尝试获得它们的正确功能。我在从 ListIterator 以前的方法中获取正确行为时遇到问题。

例如,JavaDoc 声明:

对 next 和 previous 的交替调用将重复返回相同的元素。

我的迭代器

class Node<Item> {
    public Item data;
    public Node<Item> next;
    public Node<Item> previous;

    public Node() {
        data = null;
        next = null;
        previous = null;
    }

    public Node(Item i, Node<Item> n, Node<Item> p) {
        data = i;
        next = n;
        previous = p;
    }
}

public ListIterator<Item> listIterator() {

    return new ListIterator<Item>() {

        private Node<Item> n = first;

        public boolean hasNext() {
            return n.next != last;
        }

        public Item next() {
            n = n.next;
            return n.data;
        }

        //TODO
        public void remove() {
        }

        public boolean hasPrevious() {
            return n.previous != first;
        }

        public Item previous() {
            n = n.previous;
            return n.data;
        }
    };
}

现在,当我测试它时,previous() 方法的行为不正确。

测试

LinkedList<String> lst2 = new LinkedList<String>();

    for (int i = 0; i < 4; i++)
        lst2.add("" + "data".substring(i, i + 1));

    ListIterator<String> it2 = lst2.listIterator();
    System.out.println("\nTest the list iterator.\nThe test list is " + lst2 + "\n");

    while (it2.hasNext()) {
        System.out.println("next is " + it2.next());
        System.out.println("previous is " + it2.previous());
        if (removeImplemented) {
            it2.remove();
            System.out.println("After remove: " + lst2);
        }
        System.out.println("next is " + it2.next());
    }

    System.out.println("\nHere is how the built-in Java ArrayList class works\n");
    ArrayList<String> lst3 = new ArrayList<String>();

    for (int i = 0; i < 4; i++)
        lst3.add("" + "data".substring(i, i + 1));

    ListIterator<String> it3 = lst3.listIterator();
    System.out.println("Test list iterator.\nThe test list is " + lst3 + "\n");

    boolean remove = false;

    while (it3.hasNext()) {
        System.out.println("next is " + it3.next());
        System.out.println("previous is " + it3.previous());
        if (remove) {
            it3.remove();
            System.out.println("After remove: " + lst3);
        }
        System.out.println("next is " + it3.next());
    }

我的结果

The test list is [d, a, t, a]

next is d
previous is null //incorrect
next is d
next is a
previous is d //incorrect
next is a
next is t
previous is a //incorrect
next is t
next is a
previous is t //incorrect
next is a

正确结果

The test list is [d, a, t, a]

next is d
previous is d
next is d
next is a
previous is a
next is a
next is t
previous is t
next is t
next is a
previous is a
next is a

现在,据我了解,第二组结果是ListIterator 的正确行为。那么,我能做些什么来实现这种行为呢?根据我的阅读,它与之前将光标移动到元素有关,而不是与元素本身有关。我在想办法实现这一点时遇到了麻烦。

【问题讨论】:

  • javadoc 指的是Listiteratornext()previous() 方法,但看起来您正在返回nextprevious 的任何类Node n 的字段,因此你的行为不同。
  • @DanielWiddis 那么当前的行为是否正确?
  • 取决于“正确”的含义。如果您尝试匹配ListIterator,那么显然不会,因为您的输出不匹配。我看不到你在哪里更新 n.data ,这是你返回的值,所以我不知道你想在幕后做什么。
  • 我认为在将n设置为n.prev之前需要存储n.data的值,并返回存储的n.data
  • 为了更清楚,next是“前进指针然后返回下一个值”,而previous是“返回这个值然后移动指针”。

标签: java iterator listiterator


【解决方案1】:

您已正确实现next() 的行为,前进到下一个节点并返回新值。

但是,previous() 的行为需要在您更改到上一个节点之前返回现有值。在更新n 之前,您必须将n.data 存储在临时变量中,然后返回存储的临时值。

例如:

public Item previous() {
    Item temp = n.data;
    n = n.previous;
    return temp;
}

【讨论】:

  • 有什么方法可以提供这样的例子吗?虽然它是有道理的,但我仍然无法在我的代码中实现它。
  • @23k 我更新了我的答案以包含一个具体示例。根据我的解释,这似乎微不足道。代码还有其他困难吗?
  • 我应该在哪里更新 temp?在第一次通过时,n.data == null。所以之前每次返回 temp 时,都会给出一个空值。
  • 如果你还没有做过“next()”,那么 previous 确实为空。但是一旦你完成了next(),那么n.data 中应该会有一个值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
相关资源
最近更新 更多