非常规使用Iterator迭代集合

时间:2015-07-25 12:10:44

标签: java performance for-loop while-loop iterator

我知道List<String> list的常规迭代器创建用法如下:

//Conventional-style
Iterator<String> iterator = list.iterator()
while(iterator.hasNext()){
   String string = iterator.next();
   //...further code goes here
}

但是,在Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop的接受回答中,我发现for这个不寻常的Iterator循环用法:

//Unconventional for loop style
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
    String string = iterator.next();
    //...further code goes here
}

现在,我想知道:

  1. 这种非常规样式是否会反复为每次迭代在集合上创建迭代器?或者它是某种特殊的智能for循环,它创建迭代器一次并重用它? 如果它每次都创建一个迭代器,那不应该是一个性能问题吗?
  2. 我们可以用传统风格替换while循环线 for(;iterator.hasNext();),如果我只使用for循环?
  3. PS:我很清楚集合中增强的for循环使用。我的目的是“安全”。删除元素,而不会导致ConcurrentModificationException

3 个答案:

答案 0 :(得分:4)

你称之为“非常规”的成语实际上是推荐的,因为它将迭代器变量的范围限制在使用它的循环中。

  1. 迭代器在循环开始之前创建一次。这来自for循环的一般语义,我热烈建议你熟悉它。

  2. 你可以,但你不会被推荐。这样的成语对于while成语来说是毫无意义的混淆。

  3. 最后请注意,对于99%的用例,上述所有内容都没有实际意义,因为您确实应该使用增强的循环或Java 8 forEach

答案 1 :(得分:2)

Java源自C,因此for (A; B; C) { P; }具有与A; while (B) { P; C; }相同的语义。唯一的区别是变量的范围。特别是,A部分仅执行一次。所以你的两个代码示例完全相同,但在for - 变量中,变量的范围受到限制。

迭代集合的更现代的方法是增强循环:

for (String string : list) {
    ...
}

但是,如果要在迭代时删除或更改项目,则仍需要迭代器版本。例如:

for (Iterator<String> it = list.iterator(); it.hasNext();) {
    String string = it.next();
    if (someFunction(string)) {
        it.delete();
    }
}

没有增强的for循环等效。

答案 2 :(得分:1)

<强> 1 不,它不会一遍又一遍地创建迭代器。在Java包含界面 Iterable<T> 之前,这是完美的风格。 如果要在迭代集合时删除项目,则必须使用 iterator.remove() 方法(如果已提供)。否则将抛出ConcurrentModificationException。

如果您不想在迭代集合时删除Item,那么您应该只使用for each概念,该概念由实现 Iterable<T> 接口的每个集合提供。 (链接到底有更多信息)

for (String s : yourList) {
  ... // do something with the string
}

<强> 2 是!!使用for循环习语。但正如我所说,如果你想要使用 iterator.remove() 操作,但只想迭代集合,你应该使用为每个提供的概念

您可以在此处找到有关 iterator.next() 方法缺点的大量信息,以及为什么新集成的:每个概念更好: https://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html