【问题标题】:Java - ListIterator Implementation SpecificsJava - ListIterator 实现细节
【发布时间】:2013-12-07 17:54:31
【问题描述】:

我有一个关于 ListIterators(以及,我猜是一般的迭代器)在 Java 中如何执行的快速问题。例如,一个链表(Java 的标准链表),如果我得到一个 ListIterator,它会遍历整个链表来构建它吗?我正在使用它来实现一个相当标准的哈希表,并且我担心使用迭代器而不是编写我自己的类来执行它会一直妨碍我的 O(n) 性能,而不是最坏的情况.

【问题讨论】:

  • 如何使用 List 来“实现一个相当标准的哈希表”?列表和哈希表有什么关系?
  • @LutzHorn Hashtable 的标准实现是一个“哈希桶”数组,每个桶都是一个链表。

标签: java iterator linked-list


【解决方案1】:

构建ListIterator 不会迭代List。它本质上只是初始化列表中的当前位置。

每当您致电 .next() 时,该位置都会更新。

LinkedList中的示例实现

private class ListItr implements ListIterator<E> {
    private Node<E> lastReturned = null;
    private Node<E> next;
    private int nextIndex;
    private int expectedModCount = modCount;

    ListItr(int index) {
        // assert isPositionIndex(index);
        next = (index == size) ? null : node(index);
        nextIndex = index;
    }

    public boolean hasNext() {
        return nextIndex < size;
    }

    public E next() {
        checkForComodification();
        if (!hasNext())
            throw new NoSuchElementException();

        lastReturned = next;
        next = next.next;
        nextIndex++;
        return lastReturned.item;
    }

还有ArrayList

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }

构造Iterator 不是免费的。想象一棵树:迭代它可以通过首先构建一个线性表示然后迭代该列表来实现。 (虽然我不知道这样的实现)那将是 O(N) 的构造,O(1) 每.next()

或者,您可以每次搜索下一个元素:对于每个.next(),这将是一个 O(log N) 操作,但对于创建是 O(1)。 (Java 的 TreeMap 就是这样做的)

另一种选择是构建一个节点堆栈/堆,以便您随时访问。 Guava 的TreeTraverser 使用了这种方法。每个 .next() 应该是 O(1),初始化应该是 O(1)。

【讨论】:

  • 有趣的例子,但我不确定大小等一些变量来自哪里?我认为这更多只是为了说明目的和伪代码..
  • @Opentuned,size 指 ArrayList 的大小。这确实是我在 JDK 8 中看到的实际代码。
猜你喜欢
  • 2017-11-14
  • 2016-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 2019-05-22
  • 2023-03-17
相关资源
最近更新 更多