今天看了《JAVA疯狂讲义.李刚.pdf》7.2.1 使用Iterator接口遍历集合元素。
Iterator接口主要的功能为Collection迭代器,有三个方法:
boolean hasNext();如果被迭代的元素还没有被遍历,则返回true。
(其实这是书上说的,但是我认为这么解释不太懂,又去搜了一下,觉得理解成“检查序列中是否还有元素”比较直观,就是是否还有未被迭代的集合元素)
Object next();返回集合里的下一个元素。
voidremove();删除集合里上一次next方法返回的元素。
书上的代码敲了一边,先附上:
public classTestIterator {
public static void main(String []args)
{
//创建一个集合
Collection books=new HashSet();
books.add("轻量级J2EE企业应用实战");
books.add("Struts2权威指南");
books.add("基于J2EE的Ajax宝典");
//获取books集合对应的迭代器
Iterator it=books.iterator();
while(it.hasNext())
{
//it.next()方法返回的数据类型是Object类型,需要强制类型转换
String book=(String)it.next();
System.out.println(book);
if(book.equals("基于J2EE的Ajax宝典"))
{
//从集合中删除上一次next方法返回的元素
it.remove();
System.out.println(books);
}
//对book变量赋值,不会改变集合元素本身
book="测试字符串";//1
}
System.out.println(books);
}
}
结果:
Struts2权威指南
轻量级J2EE企业应用实战
基于J2EE的Ajax宝典
[Struts2权威指南, 轻量级J2EE企业应用实战]
[Struts2权威指南, 轻量级J2EE企业应用实战]
从结果可以看出代码将元素全部遍历了一遍,且book最后的值没有影响到books中元素的值。说明修改迭代器变量的值对集合元素本身无影响,说白了迭代器变量就是个存元素值的容器而已。
Iterator迭代Collection元素时,元素不可改变,除非用了Iterator.remove();方法删除上一次next方法返回的元素。
其他与上面一样,知识while体变化了一点。
//获取books集合对应的迭代器
Iteratorit=books.iterator();
while(it.hasNext())
{
String book=(String)it.next();
System.out.println(book);
if (book.equals("Struts2权威指南"))
{
//使用Iterator迭代过程中,不可修改集合元素,下面代码引发异常
books.remove(book);
}
}
从idea可以看到,程序确实没有报错,但是执行后却是:
Struts2权威指南
Exception inthread "main" java.util.ConcurrentModificationException
atjava.util.HashMap$HashIterator.nextNode(HashMap.java:1442)
atjava.util.HashMap$KeyIterator.next(HashMap.java:1466)
atTestIteratorError.main(TestIteratorError.java:17)
看了半天,我只能理解成,while体是一个Iterator迭代块,在这里不能使用Collection.remove(),只能使用Iterator.remove()方法去除迭代元素。否则就会引发
java.util.ConcurrentModificationException。
书上还提到Iterator用的是快速失败机制,一旦发现该接口迭代过程中被其他线程修改,就会报上述那个异常,而不是显示修改后的结果,这样可以避免共享资源引发的潜在问题。这里提到的其他线程莫非就是集合中的remove方法?
明天继续看,今天就花了1.5小时看书。