`
ihyperwin
  • 浏览: 436055 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

list的remove问题

 
阅读更多
1、增强的for循环里面不能调remove()。
2、在遍历的时候不能改变ArrayList,在遍历的时候进行修改就会报错   java.util.ConcurrentModificationException.
3、集合中 在遍历一个List时不能remove 。。。。当遍历一个链表时,每个数的前后指针都是确定的 当remove一个数值时 可能使得这个链表断掉 从而造成遍历不能正常进行和结束 因此 在遍历时 是不允许remove的。。。
4、要想改变list内容,用一般的for循环!
增强for循环只能迭代,不可修改List内容,具体原因看源码,
这是ArrayList中的add方法实现的源码,内部实现是采用数组实现的!而不是采用链表!
  public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
  }
5、List是不能直接remove的。如果需要移除用迭代器!
6、迭代的时候不能直接 remove,一种办法是用 iterator.remove,ConcurrentModificationException 是说,当迭代器在跑循环时,有人把集合改了,这是不允许的,文档中明确列出了这种异常。

JCF 中说明了 ArrayList 不是一个线程集合,它不使用同步机制确保数据修改操作正确有序,但是会在迭代操作时设置版本号,在迭代器创建时保留一个版本号,每次移动指针,都要对比版 本号,如果有人改了就报错,因为这不符合约定的规则,结果是不可预料的。设计的考虑是:如果你不确信它是正确的,那就报错停下来,让程序员去修正这个不应 该出现的情况,我们不假设用什么办法能保证数据正确,因为为了性能考虑我们不保证线程安全,如果你想要线程安全就换用 Vector 之类的集合。这就像我们看到 C/C++ 的书里面介绍某些情况如果条件不符合要求的时候,结果是“未定义的”,我们这样做是明确列出“未定义的”行为需要程序员去纠正,API 不会做任何假设,它的好处是防止软件复杂性,如果随意处理未定义的行为,大型软件的复杂性就无法控制而且很难调试找到原因。
7、在循环的时候不能修改 list,set,map 等集合的值。
如果一定要修改。就用Iterator.remove();
8、一般来说,增强型for循环只适用于查询日常操作,如果你要修改只能用一般的for循环,或者引入迭代器
9、这个问题为什么会报这种异常,其实想想也不难发现。
ArrayList底层是数组实现的,假设现在有a[0]=1,a[1]=2,a[2]=3
用for循环遍历的时候
for(int i=0;i<a.length;i++){
}
假设遍历到第二个数 也就是a[1]的时候,删除了a[1] ArrayList的底层是将a[1]后面的数向前移动一个位置,由于下标改了 i没改 这样就会发生一些问题 所以就出现在遍历的时候改变整个数组 就干脆抛异常了

用迭代的方式则没这个问题









简化的for-each循环实际上只是一个语法糖,会被编译器转化成以下等价的代码:
for( Iterator<ComType> iter = ComList.iterator(); iter.hasNext();){
    ComType com = iter.next();
    if ( !com.getName().contains("abc")){
        ComList.remove(com);
    }
        }

也就是说,你在同时遍历和删除一个List,大多List实现是不允许这种操作的(某些List实现允许同时遍历和修改,例如CopyOnWriteArrayList),会抛并发修改异常。(具体可以参考ArrayList的源代码,ArrayList上面的ArrayList.iterator()操作会记录当前的修改次数modCount,remove/add操作会让修改次数自增,即modCount++,因此就能判断出来是否是并发修改了)

解决方法:

使用Iterator遍历的同时,使用Iterator.remove()删除你想删除的元素。另外也可以参考一下ListIterator,上面有很多针对List的方法。

for( Iterator<ComType> iter = ComList.iterator(); iter.hasNext();){
    ComType com = iter.next();
    if ( !com.getName().contains("abc")){
        iter.remove();
    }
}

参考网址:
http://hi.baidu.com/jack_cl/blog/item/426f22103e3cda0db8127bc1.html

分享到:
评论

相关推荐

    List.removeAll() 方法的性能效率

    在Java编程语言中,`List.removeAll()`方法是一个非常实用的函数,它允许我们从列表中一次性移除所有指定元素。这个方法是集合框架的一部分,它提供了高效的方式来进行元素的删除操作。本文将深入探讨`removeAll()`...

    list用remove实现结构体成员的删除

    总结一下,使用 `list` 的 `remove()` 方法删除结构体成员(对象实例)的关键在于找到要删除的元素,并根据其唯一的标识进行匹配。在实际编程中,我们还需要考虑到异常处理和对原列表的影响,以及选择合适的删除策略...

    基于C++ list中erase与remove函数的使用详解

    这篇文章主要讲解了`list`中的两个重要成员函数`erase`和`remove`,它们用于删除链表中的元素。理解这两个函数的正确用法对于编写高效且无误的C++代码至关重要。 首先,`erase`函数的主要作用是删除链表中特定位置...

    remove函数使用详解

    list.remove( element ) 1 参数 element:任意数据类型(数字、字符串、列表等) 2. 删除普通类型元素 删除一个列表中「存在」的数字或字符串 list1 = ['zhangsan', 'lisi', 1, 2] list1.remove(1) # 删除数字 ...

    list的正确remove姿势

    List mList = new ArrayList(); mList.add(1); mList.add(2); mList.add(3); mList.add(4); mList.add(5); /** * 正常删除 */ for (int i = 0;... mList.remove(i); } } printList(mList)

    CSharp_List.zip_C# list_C#中list_C#中list的用法_C#怎么引用List_c# list

    在C#编程中,`List&lt;T&gt;`是.NET框架中常用的一种动态数组,它属于泛型集合,提供了丰富的功能,使得在处理一系列数据时更加灵活高效。`List&lt;T&gt;`类是`System.Collections.Generic`命名空间的一部分,它实现了`IList&lt;T&gt;`...

    list to list 将list内容移到另一个list

    列表可以通过索引来访问元素,并支持多种操作,如添加元素(append、extend)、删除元素(remove、pop)、排序(sort)等。 2. **列表复制**:将一个列表的内容完全复制到另一个列表,可以使用 `copy()` 方法或切片...

    JAVA的LIST接口的REMOVE重载方法调用原理解析

    JAVA LIST接口的REMOVE重载方法调用原理解析 JAVA中的LIST接口提供了多个重载的REMOVE方法,分别传入参数为索引index、Object、Integer等,这些重载方法的调用原理是什么?在实际开发中,我们经常会遇到这种情况,...

    线性表list_array的源代码(c语言)

    int list_remove(struct list *list, int index); void list_set(struct list *list, int index, int value); void list_add(struct list *list, int index, int value); int list_lookup(struct list *list, int ...

    【Robotframework】列表List的常用操作.pdf

    如 `@{listnew} Remove Duplicates ${list}` 创建一个没有重复元素的新列表,并通过 `List Should Not Contain Duplicates ${listnew}` 检查新列表是否不包含重复项。 5. **List Should Contain Sub List**: 检查一...

    测试listBox1.Items.Remove是用ToString还是利用gethashCode来定位元素的

    标题提到的“测试`listBox1.Items.Remove`是用`ToString`还是利用`GetHashCode`来定位元素”,实际上涉及到两种不同的方法来确定元素身份。 1. **ToString()** 方法: 在C#中,`ToString()`是一个基础方法,用于将...

    Java list.remove( )方法注意事项

    `remove()`方法是`List`接口中的一个关键操作,用于从列表中删除指定的元素或根据索引移除元素。在使用`remove()`方法时,需要注意一些重要的细节以避免潜在的问题和错误。下面将详细介绍`List.remove()`方法的两种...

    Python列表list内建函数用法实例分析【insert、remove、index、pop等】

    - **语法**:`list.remove(obj)` - **参数**: - `obj`:任何数据类型,将在列表中被移除。 - **示例**: ```python my_list = [1, 2, 3, 4, 2, 5] my_list.remove(2) print(my_list) # 输出: [1, 3, 4, 2, 5] ...

    RemoveDrive卸载U盘或者移动硬盘

    在Windows命令提示符中,输入`diskpart`进入磁盘分区工具,然后输入`list disk`查看所有磁盘,找到你的U盘或移动硬盘对应的编号。 3. 接着,输入`select disk n`(n为刚刚记下的设备编号),选择目标磁盘。 4. 输入`...

    删除List中的重复值

    public static void removeDuplicate(List list) { for ( int i = 0 ; i &lt; list.size() - 1 ; i ++ ) { for ( int j = list.size() - 1 ; j &gt; i; j -- ) { if (list.get(j).equals(list.get(i))) { list....

    C#遍历List并删除某个元素的方法

    这种方式不会在原List上进行修改,而是创建了一个新的List,因此不会出现遍历中的元素位置问题。 总结一下,在C#中遍历List并删除元素时,需要注意以下几点: 1. 避免在正序遍历过程中删除元素,以免跳过某些元素。...

    java的list取之方法

    list.remove("Element to remove"); ``` #### 6. 查询元素 ```java // 检查元素是否存在 boolean contains = list.contains("Element1"); // 查找元素的位置 int index = list.indexOf("Element1"); ``` #### 7....

    C# List用法详解

    2. List.RemoveAt(int index):删除指定索引处的元素,例如:mList.RemoveAt(0); 3. List.RemoveRange(int index, int count):从指定索引处删除指定个数的元素,例如:mList.RemoveRange(3, 2); 判断某个元素是否...

    STL中list的使用

    在标准模板库(STL)中,`list`容器是一个双向链表,它提供了高效的插入和删除操作,尤其是在列表的头部或尾部进行操作时,性能尤为突出。...通过掌握上述介绍的方法,可以高效地使用`list`来解决实际问题。

    C#_StringList的用法

    aList.Remove("a"); 结果为 bcde。 2. public virtual void RemoveAt(int index):移除 ArrayList 的指定索引处的元素。 例如:ArrayList aList = new ArrayList(); aList.Add("a"); aList.Add("b"); aList.Add("c...

Global site tag (gtag.js) - Google Analytics