[Java]迭代器(Iterator)

来源:互联网 发布:二维码生成源码 编辑:程序博客网 时间:2024/06/17 08:00

迭代器(Iterator)是一个对象,它的工作是遍历并选择序列中的对象,它提供了一种访问一个容器(container)对象中的各个元素,而又不必暴露该对象内部细节的方法。通过迭代器,开发人员不需要了解容器底层的结构,就可以实现对容器的遍历。由于创建迭代器的代价小,因此迭代器通常被称为轻量级的容器。

迭代器的使用主要有以下三个方面的注意事项:
1)使用容器的iterator()方法返回一个Iterator,然后通过Iterator的next()方法返回第一个元素。
2)使用Iterator()的hasNext()方法判断容器中是否还有元素,如果有,可以使用next()方法获取下一个元素。
3)可以通过remove()方法删除迭代器返回的元素。

Iterator支持派生的兄弟成员。ListIterator只存在于List中,支持在迭代期间向List中添加或删除元素,并且可以在List中双向滚动。

Iterator的使用方法如下例所示:

package com.js;/** * Iterator使用Demo */import java.util.Iterator;import java.util.LinkedList;import java.util.List;public class Test {    public void main(String[] args){        List<String> ll = new LinkedList<String>();        ll.add("first");        ll.add("second");        ll.add("third");        ll.add("fourth");        for(Iterator<String> iterator = ll.iterator();iterator.hasNext();){            String string = (String)iterator.next();            System.out.println(string);        }    }}

运行结果为:

firstsecondthirdfourth

使用iterator()方法时经常会遇到ConcurrentModificationException异常,这通常是由于在使用Iteraor遍历容器的同时又对容器做增加或删除操作所导致的,或者由于多线程操作导致,当一个线程使用迭代器遍历容器的同时,另外一个线程对这个容器进行增加或删除操作。下列主要介绍单线程抛出ConcurrentModificationException的情况:

package com.js;/** * Iterator使用Demo */import java.util.Iterator;import java.util.LinkedList;import java.util.List;public class Test {    public void main(String[] args){        List<String> ll = new LinkedList<String>();        ll.add("first");        ll.add("second");        ll.add("third");        ll.add("fourth");        for(Iterator<String> iterator = ll.iterator();iterator.hasNext();){            String string = (String)iterator.next();            System.out.println(string);            if(string.equals("second"))                ll.add("fifth");// 抛出:ConcurrentModificationException        }    }}

运行结果为:

firstsecondException in thread "main" java.util.ConcurrentModificationExceptionat java.util.LinkedList$ListItr.checkForComodification(Unknown Source)at java.util.LinkedList$ListItr.next(Unknown Source)at com.js.Test.main(Test.java:17)

抛出上述异常的主要原因是:
在使用Iterator的时候,迭代器会新建一个线程,把原来的线程中的对象重新拷贝一份,在进行删除,修改等操作时,原来的线程只负责迭代,而Iterator负责迭代和删除操作,Iterator每次迭代都会检查迭代器里的对象和原线程中的对象个数是否一致,不一致则抛出:ConcurrentModificationException。
解决办法 :
不能使用集合中的remove方法,使用Iterrator中的remove方法。

Iterator中的removedefault void remove() 从基础集合中移除这个迭代器返回的最后一个元素(可选操作)。两个线程中都删除,保证线程的同步。

使用迭代器对象调用其中的remove方法,以保证线程同步。

正确使用方法:

 for (Iterator<String> iterator : ll.iterator() ) {           String string = (String)iterator.next();            if(string.equals("second"))                iterator.remove();        }
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 耐克赤足掉漆怎么办 鞋子买回来小了怎么办 布鞋大了一码怎么办 鞋子买小了一码怎么办 运动鞋小了一码怎么办 帆布鞋小了一码怎么办 脚踝骨韧带断了怎么办 咖啡喝多了失眠怎么办 奥迪q7电瓶没电怎么办 一岁宝宝坐不稳怎么办 2岁宝宝不肯把尿怎么办 踢足球上肢和下肢不协调怎么办 ppt文字放映时重叠怎么办 月子8天腰背疼怎么办 生完五天腰背疼怎么办 生完孩子腰不好怎么办 养了个白眼狼怎么办 孩子学东西很慢怎么办 手不小心碰肿了怎么办 腿中间摩擦的疼怎么办 晚上睡觉时双腿酸胀怎么办 腿擦破皮了怎么办 快速好 宝宝腿擦破皮了怎么办 新生儿睡觉腿喜欢弯曲怎么办 孩子八个月交叉走路怎么办 胫椎引起双腿发热怎么办 婴儿头型睡扁了怎么办 膝盖抻筋了疼怎么办 小腿肚子抻筋了怎么办 后背抻筋了 很疼怎么办 运动膝盖抻着了怎么办 大腿内侧抻着了怎么办 大腿抻筋了 很疼怎么办 小腿肚子聚筋了怎么办 6个月婴儿腿弯怎么办 胳膊抻筋拉伤了怎么办 宝宝抻着了怎么办妙招 拎东西胳膊抻了怎么办 小臂一用力筋疼怎么办 摔破胳膊很痛怎么办 胳膊的筋扭伤了怎么办