【问题标题】:Understanding Java Iterator了解 Java 迭代器
【发布时间】:2016-04-18 23:17:17
【问题描述】:

如果我运行以下代码,它将打印出 3 次重复,但是当我删除 while 循环内的 if 语句(只是为了查看它会迭代多少次)时,它会启动一个无限循环。

这个hasNext() 方法实际上是如何工作的?我认为这只会迭代 5 次,因为列表中有 5 个项目。

    public class ExerciseOne {
    public static void main(String []args){
        String []colors = {"MAGENTA","RED","WHITE","BLUE","CYAN"};
        List<String> list = new ArrayList<String>();
        for(String color : colors)
            list.add(color);
        String[] removeColors = {"RED","WHITE","BLUE"};
        List<String> removeList = new ArrayList<String>();
        for(String color : removeColors)
            removeList.add(color);

        removeColors(list,removeList);
        System.out.printf("%n%nArrayList after calling removeColors:%n");
        for(String color : list)
        {
            System.out.printf("%s ",color);
        }
    }

    private static void removeColors(Collection<String> collection1, Collection<String> collection2)
    {
        Iterator<String> iterator = collection1.iterator();

            while(iterator.hasNext()){
                if(collection2.contains(iterator.next()))
                    System.out.println("duplicate");
            }
    }

}

【问题讨论】:

  • 您阅读文档了吗?
  • hasNext 不会移动迭代器光标,iterator.next() 会移动它,所以当您删除条件时,您实际上也删除了光标更改
  • 是的当然,“如果迭代有更多元素,则返回true”,但我无法理解它何时到达列表末尾为什么它会继续循环,我会尝试找到其他一些教程或文档,因为来自 oracles 的那个对我来说不是那么清楚
  • 检查@leo的答案是否正确
  • @imoteb,它没有到达列表的末尾。如果您删除 if 条件,您将永远不会向前移动迭代器,它只会永远停留在列表的开头。

标签: java loops iteration


【解决方案1】:

其实很简单

while(iterator.hasNext()){
    if(collection2.contains(iterator.next()))
       System.out.println("duplicate");
}

假设迭代器是一个指向列表元素的指针。

当您调用next() 时,您将指针向前移动了一步。

如果您不移动指针,hasNext() 将始终为真,因为您仍在列表的开头。

所以你必须调用迭代器的next(),直到列表中没有任何剩余元素。

【讨论】:

  • 谢谢,我明白了
  • @leo 你说它就像一个指针(“想象”)。但是,它是一个指针吗?
【解决方案2】:

如果您删除 if 语句,那么它将进入无限循环,因为您的 iterator.next() 处于 if 条件中。实际上iterator.next() 是移动指针的api,而不是hasNext()hasNext() 只是检查集合中是否有任何元素。由于删除 if 语句也删除了 hasNext api,指向集合的指针没有移动,hasNext 始终返回 true。

如果你从 if 条件中取出iterator.next() 并将其移到 if 条件之上,那么即使你删除了 if 语句,循环也会重复 5 次。

Iterator<String> iterator = collection1.iterator();
while(iterator.hasNext()){
      String currentColor = iterator.next();
      if(collection2.contains(currentColor)){
         System.out.println("duplicate");
      }
}

【讨论】:

  • 感谢 Erick 指出这一点。这是我在 SO 中的第一个答案。我根据您的评论编辑了我的答案,尽管在其他答案中已正确解释。
  • 非常感谢@Erick。
【解决方案3】:
The question why Iterator is important/introduced is simple:
consider following example:
List<String> list = new ArrayList<String>();
list.add("Anurag");
list.add("Soni");
list.add("MMM");
list.add("GKP");

for(string s : list){
  if(s.equals(" Anurag")
  s.remove();
  System.out.println(s);
}

This will throw an exception-`Concurrent Modification exception` as you are trying to alter the structure of the data structure List before the iteration is completed.

so you may use Iterator for the same purpose .
Iterator iterator = List.iterator();

while(iterator.hasNext()){
String current = iterator.next();
if(current=="Anurag"){
  iterator.remove();
}else{
System.out.println(current);
}

}
OUTPUT:  Soni
         MMM
         GKP

【讨论】:

    猜你喜欢
    • 2021-01-29
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 2010-12-24
    • 2012-07-01
    • 2010-10-28
    • 1970-01-01
    相关资源
    最近更新 更多