【问题标题】:Implementing remove() Iterator Method in Java在 Java 中实现 remove() 迭代器方法
【发布时间】:2018-04-05 23:10:00
【问题描述】:

所以我正在使用通用 LinkedList,我需要能够使用迭代器来删除它的后半部分。但是,我似乎无法让它工作。这是迭代器调用:

    Iterator<String> itr = seq.iterator();
    for (int i = 0; i < N / 2; i++)
    {
        itr.next();
    }

    for (int i = 0; i < N / 2; i++)
    {
        itr.next();
        itr.remove();
    }

这是我的迭代器方法:

    boolean canRemove = false;
    int previousLoc = -1;
    Node<T> current = head;

    @Override
    public boolean hasNext()
    {
        return current != null;
    }

    @Override
    public T next()
    {
        if (hasNext())
        {
            T data = current.getData();
            current = current.getLink();
            previousLoc++;
            canRemove = true;
            return data;
        }
        throw new NoSuchElementException();
    }

    public void remove()
    {
        if (!canRemove)
        {
            throw new IllegalStateException();
        }

        SortedLinkedList.this.remove(previousLoc);
        canRemove = false;

    }

它在第二个 for 循环下的 itr.next() 调用上给出 NoSuchElementException。我最好的猜测是它可能与我确定前一个节点位置的方式有关;该类确实有一个 getPrevious() 方法:

private Node<T> getPrevious(T entry)
{
    Node<T> previous = null;
    Node<T> traverse = head;
    while (traverse != null)
    {
        //if(entry.compareTo((T) traverse.getData()) > 0)
        if (traverse.getData().compareTo(entry) < 0)
        {
            previous = traverse;
            traverse = traverse.getLink();
        }
        else
        {
            return previous;
        }
    }
    return previous;
}

还有一个getPosition方法:

public int getPosition(T anEntry)
{
    Node<T> traverse = head;
    for (int i = 0; i < manyNodes; i++, traverse = traverse.getLink())
    {
        if(anEntry.compareTo(traverse.getData()) == 0)
        {
            return i;
        }
    }
    throw new IllegalArgumentException("Element not in list");
}

但是,如果我尝试类似的东西

SortedLinkedList.this.remove(getPosition((T) getPrevious((T) current)));

我得到“solution.Node 无法转换为 java.lang.Comparable”

即使类头确实扩展了它:

public class SortedLinkedList<T extends Comparable<? super T>> implements Iterable<T>

编辑:这是删除方法:

public T remove(int givenPosition)
{
    T dataToReturn;

    if (givenPosition < 0 || givenPosition >= manyNodes)
    {
        return null;
    }
    if (givenPosition == 0)
    {
        dataToReturn = head.getData();
        head = head.getLink();
    }
    else
    {
        Node<T> previous = head;
        for (int i = 0; i < givenPosition - 1; i++)
        {
            previous = previous.getLink();
        }
        Node<T> oneToDelete = previous.getLink();
        dataToReturn = oneToDelete.getData();
        previous.setLink(oneToDelete.getLink());
        oneToDelete.setLink(null);
    }
    manyNodes--;
    return dataToReturn;
}

【问题讨论】:

  • 您的ClassCastException 正在发生,因为getPrevious 返回的是Node,而不是T
  • 我真的不明白为什么有人要重新发明轮子并创建一个集合,因为 Java 集合框架几乎拥有所有可以想象的集合类型。 “排序列表”对我来说也没有意义......
  • @UsagiMiyamoto 这是 CS II 的家庭作业。实现 remove() 值得大量额外的功劳,所以我致力于解决这个问题
  • @teppic 我能做些什么呢? getPrevious 方法中的“previous”和“traverse”字段必须是 Node 的,因为它们调用 getLink(),所以我不能真正返回 Node 以外的任何内容
  • 试试:SortedLinkedList.this.remove(getPosition((T) getPrevious((T) current).getData()));

标签: java generics linked-list iterator iteration


【解决方案1】:

试试这样的:

public void remove()
{
    if (!canRemove)
    {
        throw new IllegalStateException();
    }
    SortedLinkedList.this.remove(previousLoc--);
    canRemove = false;
}

在您的循环中,next() 的调用增加了previousLoc,而remove() 方法从列表中删除了该项目,它没有更改previousLoc 的值。因此previousLoc保持递增,而所有元素都将被删除。

要在工作中看到这一点,您应该在next()remove() 期间打印出previousLoc...

【讨论】:

  • 这个逻辑完美运行;但是,由于某种原因,分配测试说 remove() 花费的时间太长。 “java.lang.AssertionError:删除需要很长时间。从前面删除:0ns。从最后删除需要:156250000 ns。”它说它应该总是花费恒定的时间
猜你喜欢
  • 1970-01-01
  • 2019-01-05
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 2010-11-04
  • 1970-01-01
相关资源
最近更新 更多