List中 remove 方法总结.md

来源:互联网 发布:em getsel vb 编辑:程序博客网 时间:2024/05/22 00:52

List中 remove 方法总结

在for循环中使用remove 方法 导致的问题:

  1. 导致 i增加,跳过了没检测的对象
for(int i=0;i<list.size();i++){    if(list.get(i).equals("del"))        list.remove(i);}

改进:

for(int i=0;i<list.size();i++){    if(list.get(i).equals("del"))        list.remove(i);        // 由于删除后i的值变大         i--;}

2.for循环删除

for(String x:list){    if(x.equals("del"))        list.remove(x);}

抛出的异常:

Exception in thread "main" java.util.ConcurrentModificationException    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)    at java.util.ArrayList$Itr.next(ArrayList.java:851)

查看编译的class ,代码如下

List<String> list = new ArrayList(10);list.add("x");list.add("del");Iterator var2 = list.iterator();while(var2.hasNext()) {    String s = (String)var2.next();    if (s.equals("del")) {        System.out.printf("del");        list.remove(s);    }}

而在debug中list确实删除了s,而报错的代码是var2.next(),代码如下(查看AbstractList代码):

private class Itr implements Iterator<E> {    /**     * Index of element to be returned by subsequent call to next.     */    int cursor = 0;    /**     * Index of element returned by most recent call to next or     * previous.  Reset to -1 if this element is deleted by a call     * to remove.     */    int lastRet = -1;    /**     * The modCount value that the iterator believes that the backing     * List should have.  If this expectation is violated, the iterator     * has detected concurrent modification. 翻译(modCount值为list应为的值,当这个表达式不一致的情况就是 检测到并发修改的情况)     */    int expectedModCount = modCount;    public boolean hasNext() {        return cursor != size();    }    public E next() {        checkForComodification();        try {            int i = cursor;            E next = get(i);            lastRet = i;            cursor = i + 1;            return next;        } catch (IndexOutOfBoundsException e) {            checkForComodification();            throw new NoSuchElementException();        }    }    public void remove() {        if (lastRet < 0)            throw new IllegalStateException();        checkForComodification();        try {            AbstractList.this.remove(lastRet);            if (lastRet < cursor)                cursor--;            lastRet = -1;            expectedModCount = modCount;        } catch (IndexOutOfBoundsException e) {            throw new ConcurrentModificationException();        }    }    final void checkForComodification() {        if (modCount != expectedModCount)            throw new ConcurrentModificationException();    }}

查看抛出异常的代码

        final void checkForComodification() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();        }

查看相应的代码可知道该异常信息是由于modCount 不等于expectedModCount
那是什么情况导致了modCount 不等于expectedModCount?
其实是list.remove(s)导致的,查看代码如下:

public boolean remove(Object o) {    if (o == null) {        for (int index = 0; index < size; index++)            if (elementData[index] == null) {                fastRemove(index);                return true;            }    } else {        for (int index = 0; index < size; index++)            if (o.equals(elementData[index])) {                fastRemove(index);                return true;            }    }    return false;}/* * Private remove method that skips bounds checking and does not * return the value removed. */private void fastRemove(int index) {    modCount++; //  原来就是你,小样    int numMoved = size - index - 1;    if (numMoved > 0)        System.arraycopy(elementData, index+1, elementData, index,                         numMoved);    elementData[--size] = null; // clear to let GC do its work}

那如何解决呢?
1.使用ist的remove方法,使用一次跳出循环

List<String> list = new ArrayList(10);list.add("x");list.add("del");Iterator var2 = list.iterator();while(var2.hasNext()) {    String s = (String)var2.next();    if (s.equals("del")) {        System.out.printf("del");        list.remove(s);        break;    }}
  1. 直接使用itertor中remove 方法,该代码会再一次赋值,避免该问题
    tip:
    并发的情况请考虑juc中的类
原创粉丝点击