【问题标题】:How to get the current loop index when using Iterator?使用迭代器时如何获取当前循环索引?
【发布时间】:2011-03-20 18:43:22
【问题描述】:

我正在使用一个迭代器来遍历一个集合 我想获取当前元素的索引。

我该怎么做?

【问题讨论】:

标签: java iterator


【解决方案1】:

我有同样的问题,发现使用ListIterator 有效。和上面的测试类似:

List<String> list = Arrays.asList("zero", "one", "two");

ListIterator<String> iter = list.listIterator();
    
while (iter.hasNext()) {
    System.out.println("index: " + iter.nextIndex() + " value: " + iter.next());
}

确保在您真正得到next()之前之前调用nextIndex()

【讨论】:

  • 感谢您提及“确保在实际获得 next() 之前调用 nextIndex”
  • 谢谢,我以前不知道这个。我要注意的是 ListIterator 是双向的,而 Iterator 是单向的。只要您避免使用实际上是光标的东西来回移动,那么您应该是安全的。
【解决方案2】:

使用您自己的变量并在循环中递增。

【讨论】:

  • 但也请参阅@mateusz-dymczyk 关于it.nextIndex() 的建议。当集合是列表时很有用。
【解决方案3】:

这是一种使用您自己的变量并保持简洁的方法:

List<String> list = Arrays.asList("zero", "one", "two");

int i = 0;
for (Iterator<String> it = list.iterator(); it.hasNext(); i++) {
    String s = it.next();
    System.out.println(i + ": " + s);
}

输出(你猜对了):

0: zero
1: one
2: two

优点是您不会在循环中增加索引(尽管您需要小心每个循环只调用 Iterator#next 一次 - 只需在顶部执行)。

【讨论】:

  • 如果您自己创建迭代器,您也可以使用 ListIterator 并且不需要单独的 int 变量。
  • 如果你对 Arrays.asList 使用“静态导入”,那么你可以写 asList("zero", "one", "two")
  • 这正是我在阅读 Paul 的答案之前所做的。我强烈反对你的方式,因为我看不出它有什么好处。你认为有优势吗(除了提到的那个)。为什么不使用 for-each 循环?如果您使用自己的变量,则无需显式定义迭代器。
  • @progressive_overload 仅当您需要迭代器(根据问题,例如传递给库)时,示例未显示。在此示例中,您在循环外有一个变量,需要小心调用 #next 一次。在 Paul 的示例中,循环之外没有变量,但您需要小心同时调用 #next 和 #nextIndex 一次(实际上,如果多次使用,它们将被拉入局部变量,该示例没有t 显示)。
【解决方案4】:

您可以使用ListIterator 进行计数:

final List<String> list = Arrays.asList("zero", "one", "two", "three");

for (final ListIterator<String> it = list.listIterator(); it.hasNext();) {
    final String s = it.next();
    System.out.println(it.previousIndex() + ": " + s);
}

【讨论】:

    【解决方案5】:

    什么样的收藏?如果它是 List 接口的实现,那么您可以使用 it.nextIndex() - 1

    【讨论】:

      【解决方案6】:

      使用 int 并在循环中递增它。

      【讨论】:

        【解决方案7】:

        只需这样做:

                ListIterator<String> it = list1.listIterator();
                int index = -1;
                while (it.hasNext()) {
                    index++;
                    String value = it.next();
                    //At this point the index can be checked for the current element.
        
                }
        

        【讨论】:

        • 调用 indexOf() 将需要额外扫描设备列表。简单地增加一个本地计数器会更快。
        • 同意。这不是最有效的解决方案。
        • 看起来您更新了示例以提高效率。
        【解决方案8】:

        使用ListIterator 遍历集合。如果 Collection 不是 List 开头,请先使用Arrays.asList(Collection.toArray()) 将其转换为 List。

        【讨论】:

          【解决方案9】:

          您只需要使用 iterator.nextIndex() 即可返回迭代器所在的当前索引。这可能比使用您自己的计数器变量(仍然有效)要容易一些。

          public static void main(String[] args) {    
              String[] str1 = {"list item 1", "list item 2", "list item 3", "list item 4"};
              List<String> list1 = new ArrayList<String>(Arrays.asList(str1));
          
              ListIterator<String> it = list1.listIterator();
          
              int x = 0;
          
              //The iterator.nextIndex() will return the index for you.
              while(it.hasNext()){
                  int i = it.nextIndex();
                  System.out.println(it.next() + " is at index" + i); 
              }
          }
          

          此代码将一次遍历 list1 列表并打印该项目的文本,然后“位于索引处”,然后它将打印迭代器找到它的索引。 :)

          【讨论】:

          • 实际上,你的代码被关闭了,因为它试图在调用 it.next() 之后显示索引。
          • @HenrikAastedSørensen 我的代码没有差一个,但我可以理解为什么它看起来会这样。第一次调用 it.next() 时,它将返回索引 0 处的列表项。继续运行代码,您会看到,它工作得很好:)
          【解决方案10】:

          here

          iterator.nextIndex() 将提供元素的索引,随后调用next() 将返回该索引。

          【讨论】:

          • Iterator 接口没有 nextIndex() 方法。您需要为此明确使用 ListIterator,但 OP 专门质疑 Iterator。
          【解决方案11】:

          虽然你已经有了答案,但还是想补充一些信息。

          正如您明确提到的集合,您不能使用listIterator 来获取所有类型集合的索引。

          列表接口 - ArrayList、LinkedList、Vector 和 Stack。

          同时拥有iterator()listIterator()

          设置接口 - HashSet、LinkedHashSet、TreeSet 和 EnumSet。

          只有iterator()

          Map 接口 - HashMap、LinkedHashMap、TreeMap 和 IdentityHashMap

          没有迭代器,但可以通过keySet() / values()entrySet() 进行迭代,因为keySet()entrySet() 返回Setvalues() 返回Collection

          所以最好使用iterators() 连续增加一个值来获取任何集合类型的当前索引。

          【讨论】:

            【解决方案12】:

            这将是最简单的解决方案!

            std::vector<double> v (5);
            
            for(auto itr = v.begin();itr != v.end();++itr){
            
             auto current_loop_index = itr - v.begin();
            
              std::cout << current_loop_index << std::endl;
            
            }
            

            使用-std=c++11 标志在 gcc-9 上测试

            输出:

            0
            1
            2
            3
            4

            【讨论】:

            • 问题被标记为“Java”作为一种语言
            猜你喜欢
            • 2014-09-12
            • 2014-01-24
            • 2012-06-21
            • 1970-01-01
            • 1970-01-01
            • 2017-01-24
            • 2020-08-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多