# Java `Iterator`

> 原文： [https://beginnersbook.com/2014/06/java-iterator-with-examples/](https://beginnersbook.com/2014/06/java-iterator-with-examples/)

`Iterator`用于迭代（循环）各种集合类，如[`HashMap`](https://beginnersbook.com/2013/12/hashmap-in-java-with-example/)，[`ArrayList`](https://beginnersbook.com/2013/12/java-arraylist/)，[`LinkedList`](https://beginnersbook.com/2013/12/linkedlist-in-java-with-example/)等。在本教程中，我们将学习什么是迭代器，如何使用它以及使用它时会出现什么问题。`Iterator`取代了`Enumeration`，它用于迭代传统的类，如`Vector`。我们还将在本教程中看到`Iterator`和`Enumeration`之间的差异。

## 没有泛型示例的迭代器

泛型在 Java 5 中引入。在此之前，没有泛型的概念。

```java
import java.util.ArrayList;
import java.util.Iterator;

public class IteratorDemo1 {

  public static void main(String args[]){
    ArrayList names = new ArrayList();
    names.add("Chaitanya");
    names.add("Steve");
    names.add("Jack");

    Iterator it = names.iterator();

    while(it.hasNext()) {
      String obj = (String)it.next();
      System.out.println(obj);
    }
  }

}
```

**输出**：

```java
Chaitanya
Steve
Jack
```

在上面的例子中，我们在不使用泛型的情况下迭代了`ArrayList`。程序运行正常没有任何问题，但是如果你不使用泛型可能有`ClassCastException`（我们将在下一节中看到这一点）。

**另见它们：**

[如何迭代`HashMap`](https://beginnersbook.com/2013/12/how-to-loop-hashmap-in-java/ "How to loop HashMap in java")
[如何迭代`LinkedList`](https://beginnersbook.com/2013/12/how-to-loop-linkedlist-in-java/)

## 具有泛型的迭代器示例

在上一节中，我们讨论了`ClassCastException`。让我们看看它是什么以及为什么当我们不使用泛型时它会发生。

```java
import java.util.ArrayList;
import java.util.Iterator;

public class IteratorDemo2 {

  public static void main(String args[]){
    ArrayList names = new ArrayList();
    names.add("Chaitanya");
    names.add("Steve");
    names.add("Jack");

    //Adding Integer value to String ArrayList
    names.add(new Integer(10));

    Iterator it = names.iterator();

    while(it.hasNext()) {
      String obj = (String)it.next();
      System.out.println(obj);
    }
  }
}
```

输出：

```java
ChaitanyaException in thread "main" 
Steve
Jack
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at beginnersbook.com.Details.main(Details.java:18)
```

在上面的程序中，我们尝试将`Integer`值添加到`String`的`ArrayList`中，但是我们没有得到任何编译时错误，因为我们没有使用泛型。但是，由于我们在`while`循环中键入了将整数值转换为`String`，因此我们得到了`ClassCastException`。

**使用泛型：**

这里我们使用泛型，所以我们没有输入输出转换。如果您尝试在下面的程序中向`ArrayList`添加一个整数值，则会出现编译时错误。这样我们就可以避免`ClassCastException`。

```java
import java.util.ArrayList;
import java.util.Iterator;

public class IteratorDemo3 {
  public static void main(String args[]){
    ArrayList<String> names = new ArrayList<String>();
    names.add("Chaitanya");
    names.add("Steve");
    names.add("Jack");

    Iterator<String> it = names.iterator();

    while(it.hasNext()) {
      String obj = it.next();
      System.out.println(obj);
    }
 }
}
```

注意：我们没有转换输入和`iterator`返回值[`it.next()`]，因为在使用泛型时不需要它。

## `Iterator`和枚举之间的区别

集合上的[`Iterator`](https://docs.oracle.com/javase/6/docs/api/java/util/Iterator.html)。`Iterator`取代了 Java 集合框架中的`Enumeration`。迭代器在两个方面与枚举不同：

1）迭代器允许调用者在迭代期间使用明确定义的语义从底层集合中删除元素。

2）方法名称已得到改进。迭代的`hashNext()`方法替换了枚举的`hasMoreElements()`方法，同样`next()`替换了`nextElement()`。

## 使用`Iterator`时出现`ConcurrentModificationException`

```java
import java.util.ArrayList;
public class ExceptionDemo {
  public static void main(String args[]){
     ArrayList<String> books = new ArrayList<String>();
     books.add("C");
     books.add("Java");
     books.add("Cobol");

     for(String obj : books) {
        System.out.println(obj); 
        //We are adding element while iterating list
        books.add("C++");
     }
  }
}
```

输出：

```java
C
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
	at java.util.ArrayList$Itr.next(Unknown Source)
	at beginnersbook.com.Details.main(Details.java:12)
```

在迭代器上使用迭代器时，我们无法添加或删除元素。

解释自 [Javadoc](https://docs.oracle.com/javase/6/docs/api/java/util/ConcurrentModificationException.html)：
当不允许进行此类修改时，检测到并发修改对象的方法可能抛出此异常。
例如，另一个线程迭代它时，一个线程通常不允许修改`Collection`。通常，在这些情况下，迭代的结果是不确定的。如果检测到此行为，某些`Iterator`实现（包括 JRE 提供的所有通用集合实现的实现）可能会选择抛出此异常。执行此操作的迭代器称为失败快速迭代器，因为它们快速而干净地失败，而不是在未来的未确定时间冒着任意的，非确定性行为的风险。