Java Iterables 使用每个 Foreach 构造“重置”迭代器

Posted

技术标签:

【中文标题】Java Iterables 使用每个 Foreach 构造“重置”迭代器【英文标题】:Java Iterables "Resetting" Iterator With Every Foreach Construct 【发布时间】:2012-12-08 14:39:00 【问题描述】:

我相信我已经注意到,对于某些 Iterables(例如 IterableString class),要么创建了一个新的迭代器,要么迭代器以某种方式在每个新的 foreach 构造中重新开始,但这似乎不会发生在其他可迭代...

例如,如果您运行以下代码:


import java.util.ArrayList;


public class test 


  public static void main(String args[]) 
    IterableString x = new IterableString("ONCE");

    System.out.println("***");
    for (char ch : x)
      System.out.println(ch);
    

    System.out.println("***");
    for (char ch : x)
        System.out.println(ch);
     

    ArrayList y = new  ArrayList();
    y.add('T');
    y.add('W');
    y.add('I');
    y.add('C');
    y.add('E');

    System.out.println("***");
    for (char ch : y)
        System.out.println(ch);
     

    System.out.println("***");
    for (char ch : y)
        System.out.println(ch);
     

    System.out.println();
  


您将看到以下输出:


***
O
N
C
E
***
***
T
W
I
C
E
***
T
W
I
C
E

带有 x 的第二个 foreach 循环似乎从它停止的地方开始(在最后一项之后),但是带有 y 的第二个 foreach 循环似乎从它第一次开始的地方开始(在第一项)。为什么会这样?我们如何才能让 Iterables 表现得像后者(ArrayLists)?

更具体地说,我们将如何修改像 IterableString 这样的类以像 ArrayList 一样工作?

【问题讨论】:

IterableString 到底是什么??该未知对象可能与迭代器的配置方式有关... Iterable 的 Javadoc 似乎并没有说太多,以便强制每次调用 iterator() 返回一个新的 Iterator - 但这似乎是 JDK 接受的做法(和明智的)。所以它看起来像一个“错误”,由谁创建了IterableString 【参考方案1】:

ArrayList 能够在 java foreach 循环中被迭代,因为它在 Java 中实现了 Iterable 接口。 Iterable 接口概述了一个方法iterator,它返回集合的迭代器。在 Java 中使用 foreach 循环在后台使用此方法的迭代器。每次创建新的 foreach 循环时,ArrayList 都会提供一个新的迭代器。

如果你想创建一个可以在 Java 中使用 foreach 循环进行迭代的类,你需要实现 Iterable 接口并定义如何迭代集合。

【讨论】:

这仍然没有解决 OP 的问题 我对@Code-Guru 的评论感到有些困惑。也许我误解了这个问题,但我概述了为什么 ArrayList 在 foreach 循环中有这种行为以及如何在用户定义的类中模仿它。 问题是为什么IterableString 类的行为与ArrayList 不同。【参考方案2】:

IterableString 类(由您的linked article 定义)既是Iterable,又是Iterator。这是否是一个好主意值得商榷 - 但一个简单的解决方法是:

  // This method implements Iterable.
  public Iterator<Character> iterator() 
    return new IterableString(this.str);
  

【讨论】:

谢谢!我被我在其他可迭代对象中看到的类似问题所困扰(例如this one,其中嵌套迭代器类有另一个问题,它需要考虑到它对更改其外部类中的组件具有状态意识)。出于某种原因,错误的表面上的一致性给我的印象是,像 ArrayList 这样的可迭代对象发生了一些特殊的事情,而不是我正在查看的非标准可迭代对象中的碎片。

以上是关于Java Iterables 使用每个 Foreach 构造“重置”迭代器的主要内容,如果未能解决你的问题,请参考以下文章

python 中zip()函数的使用

Guava之Iterables使用示例

java怎么获取list的每个元素?

Angular NgFor 仅支持绑定到 Iterables,例如 Arrays

如何映射任意Iterables?

在 python3 中:list(iterables) 的奇怪行为