迭代器可以改变迭代的集合吗?Java的

Jon*_*ych 6 java iterator

我试图使用迭代器中的迭代次数作为计数器,但是想知道这样做的后果.

private int length(Iterator<?> it) {
    int i = 0;

    while(it.hasNext()) {
        it.next();
        i++;
    }

    return i;
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我担心迭代器可能在幕后做什么.也许当我迭代堆栈时,它会弹出堆栈中的项目,或者如果我使用优先级队列,它会修改优先级.

关于迭代器的javadoc说这个:

next
E next()
返回迭代中的下一个元素.
返回:
迭代中的下一个元素
抛出:
NoSuchElementException - 如果迭代没有更多元素

我没有看到保证迭代这个未知的集合不会修改它.我是在考虑不切实际的边缘情况,还是这是一个问题?有没有更好的办法?

dim*_*414 6

Iterator简单地提供了一个接口转换成某种流的,因此它不仅是完全有可能next()以某种方式破坏数据,但它甚至可以将数据在Iterator是唯一的,不可替代的.

我们可以拿出更多的直接的例子,但一个简单的一种是IteratorDirectoryStream.虽然在DirectoryStream技术上Iterable,它只允许Iterator构造一个,所以如果你试图做以下事情:

Path dir = ...
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
  int count = length(stream.iterator());
  for (Path entry: stream) {
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

您将在foreach块中获得异常,因为流只能迭代一次.总而言之,您的length()方法可能会更改对象并丢失数据.

此外,没有理由Iterator必须与某个单独的数据存储相关联.以我几个月给出答案为例,提供一种选择n随机数的简洁方法.通过使用无限,Iterator我们能够懒惰地提供,过滤和传递任意大量的随机数据,无需一次性存储,甚至计算它们直到需要它们.因为Iterator它不支持任何数据结构,所以查询它显然具有破坏性.

既然如此,这些例子并没有使你的方法变坏.请注意,Guava库(每个人都应该使用)提供了一个Iterators类,其中包含您在上面详述的行为,称为size()符合Collections Framework.然后,这些方法的用户需要知道他们正在使用什么类型的数据,并避免进行不小心的调用,例如尝试计算Iterator他们知道无法替换的结果数量.