list iterator remove中的remove方法怎么使用

在遍历集合时,想将符合条件的某些元素删除,开始是用了下面的方法
public&static&void&main(String[]&args)&throws&UnsupportedEncodingException&{&&
&&&&List&String&&list&=&new&ArrayList&String&();&&
&&&&list.add("abc");&&
&&&&list.add("bbc");&&
&&&&list.add("cbc");&&
&&&&Iterator&String&&it&=&list.iterator();&&
&&&&while(it.hasNext()){&&
&&&&&&&&String&str&=&it.next();&&
&&&&&&&&System.out.println(str);&&
&&&&&&&&if(str.equals("abc")){&&
&&&&&&&&&&&&list.remove(str);&&
&&&&&&&&}&&
结果报下面的异常
Exception in thread "main"&.util.ConcurrentModificationException&& &at java.util.AbstractList$Itr.checkForComodification(Unknown Source)&& &at java.util.AbstractList$Itr.next(Unknown Source)&& &at junit.Test.main(Test.java:23)
查了下,原来java中的集合边遍历边删除是需要使用迭代器中的方法的,改为下面
public static void main(String[] args) throws UnsupportedEncodingException {
List&String& list = new ArrayList&String&();
list.add("abc");
list.add("bbc");
list.add("cbc");
Iterator&String& it = list.iterator();
while(it.hasNext()){
String str = it.next();
System.out.println(str);
if(str.equals("abc")){
it.remove();
System.out.println(list.size());
阅读(...) 评论()2013年10月 Java大版内专家分月排行榜第二2013年3月 Java大版内专家分月排行榜第二2013年2月 Java大版内专家分月排行榜第二
2013年7月 Java大版内专家分月排行榜第三2013年5月 Java大版内专家分月排行榜第三2013年4月 Java大版内专家分月排行榜第三
2013年10月 Java大版内专家分月排行榜第二2013年3月 Java大版内专家分月排行榜第二2013年2月 Java大版内专家分月排行榜第二
2013年7月 Java大版内专家分月排行榜第三2013年5月 Java大版内专家分月排行榜第三2013年4月 Java大版内专家分月排行榜第三
2013年10月 Java大版内专家分月排行榜第二2013年3月 Java大版内专家分月排行榜第二2013年2月 Java大版内专家分月排行榜第二
2013年7月 Java大版内专家分月排行榜第三2013年5月 Java大版内专家分月排行榜第三2013年4月 Java大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。最近在看《数据结构与算法分析》(Java语言描述)一书,看到第3.3.2 这一节时介绍Iterator接口。书中说道,“Iterator接口中包含一个方法,叫做remove()。该方法可以删除next最新返回的项。虽然Collection接口也包含一个remove方法,但是,使用Iterator的remove可能有更多的优点。”
那么首先我们知道Collection接口是继承于Iterator接口,如下图所示:
那么Collection接口中的remove()比Iterator接口中的remove()的差异性到底在哪呢?我们可以先从他们的API中看出方法的不一样。如下图所示:
第一张是Iterator接口中的remove(),第二张是Collection接口中的remove()。
那么从方法体上看有着明显的不同了,Collection接口中的remove方法必须接受一个对象,即要从集合中移除的对像,并且返回boolean值。而Iterator接口中的remove方法,它通过迭代器,每次使用next后,让指针往后移一位后,再使用remove方法移除当前指针指向的对象(这个Iterator接口中的next方法和remove方法之间的关系,大家感兴趣可以查一下资料或者自行看一下java源码),然后他的方法是void的,没有返回值的。
那好,使用Iterator的remove方法优点之一就是:
Collection的remove方法必须首先找出要被删除的项。因此如果知道所要删除的项的准确位置,那么删除它的开销很可能要小得多。(如果不知道呢,那么首先得找到这个对象的位置,了解单链表结构的同学都知道,单链表的查询效率比较低,它得从表头一个个遍历了比较才能找到这个对象)但是下一节我们将要看到一个例子,是在集合中每隔一项删除一项。这个程序用迭代器很容易编写,而且比用Collection的remove方法潜藏着更高的效率。
然后书中接着介绍到:“当直接使用Iterator(而不是通过一个增强的for循环间接使用)时,重要的是要记住一个法则:如果对正在被迭代的集合进行结构上的改变(即对该集合使用add、remove或clear方法),那么迭代器就不再合法(并且在其后使用该迭代器时将会有ConcurrentModificationException异常抛出)。为了避免呆呆起准备给出某一项作为下一项(nextitem)而该项此后或者被删除,或者也许一个新的项正好插入该项的前面这样一些讨厌的情形,有必要记住上述法则。这样意味着,只有在需要在立即使用一个迭代器的时候,我们才应该获取迭代器。然后,如果迭代器用了他自己的remove方法,那么这个迭代器就仍然合法的。这是有时候更愿意使用迭代器的remove方法的第二个原因。”
好,当我读完上一段时候,我得到了2个信息。
当我们在遍历集合时,如果这当中出现改变集合结构的操作(add、remove或clear方法),会抛出ConcurrentModificationException异常。
但是,当我们获取这个集合的迭代器然后用迭代器进行遍历时,出现改变集合结构的操作,不会抛出异常。
后来发现我第二个信息的理解是错的,当我们获取这个集合的迭代器然后用迭代器进行遍历时,只有迭代器用了他自己的remove方法时,才不会报异常,如果你执行了其他可能改变集合结构的操作它还是会抛异常。因为只有Iterator接口的方法是安全的。而Iterator接口中只提供了三个方法:
只有remove方法是能改变集合结构的,并没有提供其它改变集合结构的方法。所以,在集合遍历时,你使用Collection接口提供的方法改变集合结构,就会报异常的。你使用Iterator接口中的remove方法就不会报异常,具体是为什么呢?在这里大家可以看这个这位朋友的博客
本文已收录于以下专栏:
相关文章推荐
一、遍历集合的方式有很多,这里就以List 为例
如果是单线程的我们一般使用: int  len= list.size()
for (int i=0;i&i++){
如果是多线程的程序...
从集合的体系图上我们可以看到,List 和  Set 集合都是继承自 Collection 的,由此可以看出。Collection是除Map集合以外所有集合的祖宗。由此可见它的重要性。集合,有别于其他...
在使用list 结合的时候习惯了 list=null ;在创建这样的方式,但是发现使用list的clear 方法很不错,尤其是有大量循环的时候
1、list 接口  的ArrayList 类的cle...
容器Collection接口下面可以实现HashSet类,
在HashSet类中有add、remove等方法,
add方法可以往容器中添加元素,
而remove(“example”)可...
ListIterator接口继承自Iterator接口,新增了add()方法。关于ListIterator的add()以及remove()方法的作用,《java核心技术 卷I》里如下表述可能有点歧义,...
转载自:http://blog.csdn.net/scyatcs/article/details/9003295
一、Iterator的API
关于Iterator主要有三个方法:hasNext(...
Java循环中remove方法的使用首先看下如下代码public class Test
public static void main(String[] args)
List ll = new...
public void persist(Object entity)
persist方法可以将实例转换为managed(托管)状态。在调用flush()方法或提交事物后,实例将会被插...
直接上代码:
package com.itany.linkedL
import java.util.I
import java.util.LinkedL
IO_REMOVE_LOCK(删除锁)的具体结构没有公开,WDK的文档中中查不到IO_REMOVE_LOCK。最开始看到IO_REMOVE_LOCK是在WDK的例子event中。下面是参考网上的一些资...
他的最新文章
讲师:王哲涵
讲师:王渊命
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
会报异常ConcurrentModificationException
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
当然不能用map.remove()啦,所以才会有iterator.remove()这么个API让你用啊。
使用map.remove()有可能会导致iterator失效,但iterator.remove是专门设计用来在遍历过程中删除元素的,所以不会有这个问题。
同步到新浪微博
分享到微博?
Hi,欢迎来到 SegmentFault 技术社区!⊙▽⊙ 在这里,你可以提出编程相关的疑惑,关注感兴趣的问题,对认可的回答投赞同票;大家会帮你解决编程的问题,和你探讨技术更新,为你的回答投上赞同票。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:import java.util.ArrayL
import java.util.C
import java.util.I
public class Name {
&private String firstName,lastN
&public Name(String firstName, String lastName) {
&&super();
&&this.firstName = firstN
&&this.lastName = lastN
&public String getFirstName() {
&&return firstN
&public void setFirstName(String firstName) {
&&this.firstName = firstN
&public String getLastName() {
&&return lastN
&public void setLastName(String lastName) {
&&this.lastName = lastN
&@Override
&public int hashCode() {
&&final int prime = 31;
&&int result = 1;
&&result = prime * result
&&&&+ ((firstName == null) ? 0 : firstName.hashCode());
&&result = prime * result
&&&&+ ((lastName == null) ? 0 : lastName.hashCode());
&@Override
&public boolean equals(Object obj) {
&&if (this == obj)
&&if (obj == null)
&&if (getClass() != obj.getClass())
&&Name other = (Name)
&&if (firstName == null) {
&&&if (other.firstName != null)
&&} else if (!firstName.equals(other.firstName)){
&&if (lastName == null) {
&&&if (other.lastName != null)
&&} else if (!lastName.equals(other.lastName)){
&public static void main(String[] args) {
&&Collection&Name& c=new ArrayList&Name&();
&&c.add(new Name(&wang&,&delei&));
&&c.add(new Name(&sun&,&hao&));
&&c.add(new Name(&zhu&,&lei&));
&&for(Iterator&Name& it=c.iterator();it.hasNext();){
&&&Name name=(Name)it.next();
&&&if(name.getLastName().length()&4)
&&&&it.remove();
&&&&//c.remove(name);&&结果不正确
&&for(Name name:c){
&&&System.out.println(name.getFirstName());
以下内容转载:
原因: jdk5.0以上的for-each也是利用内部的iterator来遍历集合的(跟以前的iterator一样)获得的Iterator是一个内部类产生的迭代器,这个迭代器在调用next方法时,会检查列表是否被修改过,如果被修改过,就会抛出ConcurrentModificationException异常。进一步说,当使用
fail-fast iterator 对
Collection 或 Map 进行迭代操作过程中尝试直接修改
Collection / Map 的内容时,即使是在单线程下运xi,java.util.ConcurrentModificationException
异常也将被抛出。Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。
Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照
fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。  所以
Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用
Iterator 本身的方法
remove() 来删除对象,Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。
有意思的是如果你的
Collection / Map 对象实际只有一个元素的时候, ConcurrentModificationException 异常并不会被抛出。这也就是为什么在 javadoc 里面指出: it would be wrong to write a program that depended on this exception for its correctness:
ConcurrentModificationException should be used only to detect bugs.
解决方法:在Map或者Collection的时候,不要用它们的API直接修改集合的内容,如果要修改可以用Iterator的remove()方法
由于for-each的写法,使我们无法获得iterator对象,所以这种遍历方式不能进行删除操作。只好改成了比较土的方法实现了,如下:
&&&&&&&&&&& for (Iterator it = desk.getPkers().iterator(); it.hasNext();) {&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&& PKer pkerOnDesk =(PKer) it.next();&&
&&&&&&&&&&&&&&&&&& it.remove();
&&&&&&&&&&& }
本文已收录于以下专栏:
相关文章推荐
遍历删除List中的元素有很多种方法,当运用不当的时候就会产生问题。下面主要看看以下几种遍历删除List中元素的形式:
1.通过增强的for循环删除符合条件的多个元素
2.通过增强的for循环删除...
在遍历集合时,想将符合条件的某些元素删除,开始是用了下面的方法
public static void main(String[] args) throws UnsupportedEncodingE...
在java中如果我们需要遍历集合并删除其中的某些元素时,例如对于List来说,我们有三种办法。
1. 普通的for循环遍历并删除
import java.util.*;
public class...
Iterator接口的remove方法将会删除上次调用next方法时返回的元素,如果想要删除指定位置上的元素,需要越过这个元素
Iterator it= c.iterator();
it.next...
有序否允许元素重复否Collection否是List是是SetAbstractSet否否HashSetTreeSet是(用二叉树排序)MapAbstractMap否使用key-value来映射和存储数...
一、遍历集合的方式有很多,这里就以List 为例
如果是单线程的我们一般使用: int  len= list.size()
for (int i=0;i&i++){
如果是多线程的程序...
1.序列容器,比如vector
序列容器的erase返回的是被删除元素后的有效迭代器。
for(iter = vec.be...
void remove()从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。如果进行迭代时用调用此方法之外的其他方式修改了该迭代...
int[] selects = table.getSelectionIndices();
                boolean flag = MessageDialog.openQuest...
101:对引用类型执行sizeof运算得到被引用对象所占空间的大小;对数组执行sizeof得到整个数组所占空间的大小。sizeof运算不会把数组转换成指针处理;对string对象或者vector对象执...
他的最新文章
讲师:王哲涵
讲师:王渊命
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 list iterator remove 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信