【问题标题】:java- reset list iterator to first element of the listjava-将列表迭代器重置为列表的第一个元素
【发布时间】:2012-11-21 06:36:17
【问题描述】:

我需要知道如何将 LinkedList 迭代器“重置”为其第一个元素。

例如:

LinkedList<String> list;

Iterator iter=list.listIterator;

iter.next();

iter.next();

一遍又一遍,在迭代器多次移动之后,我需要“重置”迭代器的位置。 `

我想问如何将我的迭代器“重置”为第一个元素

我知道我可以通过这种方式获取第一个元素的列表迭代器:

iter= list.listIterator(1);

这是最好的解决方案吗?或者我错过了 Oracle 文档中的某些内容?

【问题讨论】:

  • 为什么不创建一个新的迭代器?
  • 你错过了一些东西,如果你需要做的比下一个甚至上一个更多,迭代器不是最好的选择。为什么需要重置?
  • 我试图理解java中动态列表的概念。几周前,我在 jsp oage 上遇到了会话变量问题。从 EL 和 taglibs 我可以使用迭代器的方法,但我无法重新定义它(我仍然对 jsp 知之甚少,但我仍在改进它:))当你写“迭代器不是最佳选择”时你介意什么?你能给我解释一下吗? :)

标签: java iterator


【解决方案1】:

您可以再次调用listIterator 方法来获取指向列表开头的迭代器实例:

iter = list.listIterator();

【讨论】:

【解决方案2】:

最好不要使用LinkedList,通常它在所有学科中都比较慢,而且不太方便。 (主要在前面插入/删除时,尤其是大数组LinkedList更快)

使用ArrayList,并使用

进行迭代
int len = list.size();
for (int i = 0; i < len; i++) {
  Element ele = list.get(i);
}

重置很简单,只需再次循环即可。
如果你坚持使用迭代器,那么你必须使用新的迭代器:

iter = list.listIterator();

(我一生中只见过一次 LinkedList 的优势:我可以通过 while 循环循环并删除第一个元素)

【讨论】:

  • 主要在前面删除和插入时LinkedList更快。
  • 在 LinkedList 的情况下,即使从中间删除项目也更快。也就是说,如果您正在使用 iterator.remove() 迭代和删除项目。 ArrayList 将需要移动剩余项目。
  • @Sohaib,是的,主要取决于列表的大小。最多特定数量的元素 System.arraycopy,内部使用 C-memcopy,用于移动数组更快。高级实现根据元素大小切换底层实现。
【解决方案3】:

如果顺序无关紧要,我们可以使用hasPrevious()previous() 方法使用相同的迭代器重新向后 迭代:

ListIterator<T> lit = myList.listIterator(); // create just one iterator

最初迭代器位于开头,我们进行 forward 迭代:

while (lit.hasNext()) process(lit.next()); // begin -> end

然后迭代器位于最后,我们可以进行向后迭代:

while (lit.hasPrevious()) process2(lit.previous()); // end -> begin

【讨论】:

  • 嗯 @ryenus...我喜欢你的想法,即在 ' 之后使用 hasPrevious()previous() 从最后一个元素向后迭代发生了向前的迭代。如果您需要使用相同的迭代器实例,这似乎是一个完美的解决方案(不知道为什么您实际上需要一遍又一遍地使用相同的实例)。我很好奇循环回到迭代的开始是否比创建一个新的迭代器实例更便宜,但我想这在某种程度上也取决于列表的大小。
【解决方案4】:

这是一种替代解决方案,但有人可能会争辩说它没有增加足够的价值使其值得:

import com.google.common.collect.Iterables;
...
Iterator<String> iter = Iterables.cycle(list).iterator();
if(iter.hasNext()) {
    str = iter.next();
}

如果是结尾,调用 hasNext() 会将迭代器光标重置到开头。

【讨论】:

  • 这听起来像是您发现的怪癖,而不是界面保证的东西。
【解决方案5】:

在 Collection impl 上调用 iterator(),可能会在每次调用时获得一个新的 Iterator。

因此,您只需再次拨打iterator() 即可获得新的。


代码

IteratorLearn.java

import org.testng.Assert;
import org.testng.annotations.Test;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

/**
 * Iterator learn.
 *
 * @author eric
 * @date 12/30/18 4:03 PM
 */
public class IteratorLearn {
    @Test
    public void test() {
        Collection<Integer> c = new HashSet<>();
        for (int i = 0; i < 10; i++) {
            c.add(i);
        }

        Iterator it;

        // iterate,
        it = c.iterator();
        System.out.println("\niterate:");
        while (it.hasNext()) {
            System.out.printf("\t%d\n", it.next());
        }
        Assert.assertFalse(it.hasNext());

        // consume,
        it = c.iterator();
        System.out.println("\nconsume elements:");
        it.forEachRemaining(ele -> System.out.printf("\t%d\n", ele));
        Assert.assertFalse(it.hasNext());
    }
}

输出:

iterate:
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

consume elements:
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

【讨论】:

    【解决方案6】:

    您可能真正想要使用的是Iterable,它可以通过调用iterator() 多次返回新的Iterator

    //A function that needs to iterate multiple times can be given one Iterable:
    public void func(Iterable<Type> ible) {
        Iterator<Type> it = ible.iterator(); //Gets an iterator
        while (it.hasNext()) {
            it.next();
        }
        it = ible.iterator(); //Gets a NEW iterator, also from the beginning
        while (it.hasNext()) {
            it.next();
        }
    }
    

    您必须事先定义 iterator() 方法的作用一次:

    void main() {
        LinkedList<String> list; //This could be any type of object that has an iterator
        //Define an Iterable that knows how to retrieve a fresh iterator
        Iterable<Type> ible = new Iterable<Type>() {
            @Override
            public Iterator<Type> iterator() {
                return list.listIterator(); //Define how to get a fresh iterator from any object
            }
        };
        //Now with a single instance of an Iterable,
        func(ible); //you can iterate through it multiple times.
    }
    

    【讨论】:

      【解决方案7】:

      您可以做的是,使用 while 循环手动将迭代器设置到第一个位置。

      while(iter.hasPrevious())
      {
          iter.previous();
      }
      

      当您退出循环时,您的迭代器将位于位置 0

      抱歉有语法错误

      【讨论】:

        猜你喜欢
        • 2016-09-21
        • 2011-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-16
        • 1970-01-01
        • 2020-09-03
        • 2015-05-16
        相关资源
        最近更新 更多