ArrayList之remove()方法

  arraylist中的remove方法:

public E remove(int index) {
      // 先检查下标索引是是否越界
      rangeCheck(index);
      // ArrayList的修改次数加1
      modCount++;
      // 获取索引对应的元素值
      E oldValue = elementData(index);
      // 获取删除元素后,需要移动的元素的个数
      int numMoved = size - index - 1;
      if (numMoved > 0)
          // 将元素进行移动拷贝
          System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
      // 最后将多出的位置设置为空,这样说明是没有引用的对象了
      elementData[--size] = null; // Let gc do its work
      // 返回删除的旧值
      return oldValue;
}

  调用过一次该方法,modCount就会加1,后面遍历时发现是通过使用这个字段来判断,当前的集合类是否被并发修改。

会有ConcurrentModificationException异常。

  

public static void main(String[] args) {
        List<Integer> list=new ArrayList<>();
        list.add(4);
        list.add(6);
        list.add(2);
        list.add(8);
        list.add(9);
        for (Integer integer : list) {
            if (integer==4) {
                //移除的是索引序号为4的值
                list.remove((int)integer);
            }
        }
        System.out.println(list);
    }

  for循环其实是调用了Iterator即如下的方法实现,每次遍历会进入next()方法,就会进行checkForComodification()方法,如果已经修改了即modCount++,可是expectedModCount就是初始的值,两者不相同即会抛出异常。

  解决方法:在remove()方法结束时加break,跳出循环即可。

  ArrayList中Iterator迭代器的实现:

private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

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

  

说明:
① 在初始化Itr时expectedModCount = modCount = 8 。
② 在执行next方法的第一步先进行了checkForComodification方法的检查,因为我们之前进行了remove操作,那么modCount数值加一,实际modCount = 9 。
③ modCount 数值和expectedModCount 数值不相等,抛出ConcurrentModificationException异常。
 
   arrayList中索引的问题:
  
    List<Integer> list=new ArrayList<>();
    list.add(2);
    list.add(3);
    list.add(4);

  list.remove(Integer),它是寻找Integer这个值在做删除操作。

  若想以Integer为索引进行删除操作,必须进行强转操作,即list.remove((int)Integer);

猜你喜欢

转载自www.cnblogs.com/weson/p/10920831.html