Iterator
用于迭代(循环)各种集合类,如HashMap
,ArrayList
,LinkedList
等。在本教程中,我们将学习什么是迭代器,如何使用它以及使用它时会出现什么问题。Iterator
取代了Enumeration
,它用于迭代传统的类,如Vector
。我们还将在本教程中看到Iterator
和Enumeration
之间的差异。
没有泛型示例的迭代器
泛型在 Java 5 中引入。在此之前,没有泛型的概念。
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);
}
}
}
输出:
Chaitanya
Steve
Jack
在上面的例子中,我们在不使用泛型的情况下迭代了ArrayList
。程序运行正常没有任何问题,但是如果你不使用泛型可能有ClassCastException
(我们将在下一节中看到这一点)。
具有泛型的迭代器示例
在上一节中,我们讨论了ClassCastException
。让我们看看它是什么以及为什么当我们不使用泛型时它会发生。
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);
}
}
}
输出:
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
。
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
。Iterator
取代了 Java 集合框架中的Enumeration
。迭代器在两个方面与枚举不同:
1)迭代器允许调用者在迭代期间使用明确定义的语义从底层集合中删除元素。
2)方法名称已得到改进。迭代的hashNext()
方法替换了枚举的hasMoreElements()
方法,同样next()
替换了nextElement()
。
使用Iterator
时出现ConcurrentModificationException
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++");
}
}
}
输出:
C
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayListItr.checkForComodification(Unknown Source)
at java.util.ArrayListItr.next(Unknown Source)
at beginnersbook.com.Details.main(Details.java:12)
在迭代器上使用迭代器时,我们无法添加或删除元素。
解释自Javadoc:
当不允许进行此类修改时,检测到并发修改对象的方法可能抛出此异常。
例如,另一个线程迭代它时,一个线程通常不允许修改Collection
。通常,在这些情况下,迭代的结果是不确定的。如果检测到此行为,某些Iterator
实现(包括 JRE 提供的所有通用集合实现的实现)可能会选择抛出此异常。执行此操作的迭代器称为失败快速迭代器,因为它们快速而干净地失败,而不是在未来的未确定时间冒着任意的,非确定性行为的风险。