为什么Iterator不在for循环中“Move Next”

时间:2015-05-24 16:50:07

标签: java iterator

我正在学习迭代,并使用以下私有属性在我的'CStickChart'类上实现了一个Iterator:

  private List<CStick> cStickCollection = new ArrayList<CStick>();

然后实现返回CSticks的方法:

  public Iterator<CStick> iterator() {
    return this.cStickCollection.iterator();
  }

现在当我尝试迭代它时,我能够使用指定的localCStick执行此操作,但是在CStickChart Iterator上调用next()方法并不能达到我的预期。我希望它能在我的CStickChart中给我下一个CStick(因此当我调用getEPIC时,我希望它能给我下一个EPIC)。

// Print the EPIC out of the Array using the iterator
for (CStick localCStick : testCStickChart) {
  System.out.println(localCStick.getEPIC());
  //The below line doesn't return the next CStick and I'm not sure why
  System.out.println("next EPIC is " + testCStickChart.iterator().next().getEPIC());
}

请有人解释为什么不是这种情况(它总是返回第一个EPIC)

4 个答案:

答案 0 :(得分:1)

System.out.println("next EPIC is " + testCStickChart.iterator().next().getEPIC());

这是因为在这一行中你将在循环的每次迭代中获得一个新的迭代器。每个新的迭代器都会从列表的开头重新开始。

答案 1 :(得分:0)

因为您使用cStickCollection获得了.iterator()的顶级迭代器。我认为您希望在循环中使用与iterator位置相同的位置,并在下一个元素使用peek。你不能通过for-each循环执行此操作,而且一般情况下也不能使用Iterator(因为他们不会实现peek )。

相反,您可以在for上使用传统的cStickCollection循环

for (int i = 0, len = cStickCollection.size(); i < len; i++) {
    CStick localCStick = cStickCollection.get(i);
    System.out.println(localCStick.getEPIC());
    if (i + 1 < len) { // <-- check that there is a "next"
        System.out.println("next EPIC is "+cStickCollection.get(i+1).getEPIC());
    }
}

答案 2 :(得分:0)

每次在该循环内部调用testCStickChart.iterator()时,都会创建一个新的迭代器对象。因此,对next()的每次调用都在一个新的迭代器对象上执行,返回第一个对象。你想要做的是在循环之前声明一个新的Iterator<CStick>并在循环中使用它,如下所示:

Iterator<CStick> it = testCStickChart.iterator();
// Print the EPIC out of the Array using the iterator
for (CStick localCStick : testCStickChart) {
    System.out.println(localCStick.getEPIC());
    //The below line doesn't return the next CStick and I'm not sure why
    System.out.println("next EPIC is " + it.next().getEPIC());
}

答案 3 :(得分:0)

听起来你不想使用增强的 - for结构。原因是:增强型 - for具有可迭代实体will use the iterator provided internally,并且只会前进。

这也意味着在该循环内对iterator的任何调用都会产生一个从迭代的开始开始的迭代器。

因此,有了这个,你有两个选择 - 两个都涉及放弃增强版 - for

  • 使用带索引的标准for循环来向后和向前推进列表,或
  • 使用List提供的ListIterator以非常无缝的方式前后移动。

这是一个使用整数的例子 - 请注意,每次我推进迭代器时,我都必须将它移回到它之前的位置,这样我就不会再推进它。而且,一旦我们用完了元素,我就有条件摆脱循环。

List<Integer> integerList = new ArrayList<Integer>() {{
    add(1);
    add(2);
    add(3);
    add(4);
    add(5);
    add(6);
    add(7);
    add(8);
    add(9);
    add(10);
}};

for (ListIterator<Integer> iterator = integerList.listIterator(); iterator.hasNext(); ) {
    int value = iterator.next();
    int nextValue = Integer.MIN_VALUE;
    if (iterator.hasNext()) {
        nextValue = iterator.next();
        // Reset the state of the iterator
        iterator.previous();
    }

    System.out.println("Value = " + value);
    if(nextValue != Integer.MIN_VALUE) {
        System.out.println("Next value = " + nextValue);
    }
}
相关问题