在循环中 删除list中元素


JAVA中循环遍历list有三种方式for循环、增强for循环(也就是常说的foreach循环)、iterator遍历。

遍历

1、for循环

	for(int i=0;i<list.size();i++){
	    if(list.get(i).equals("del"))
	        list.remove(i);
	}

这种方式的问题在于:删除某个元素后,list的大小发生了变化,而你的索引也在变化,所以会导致你在遍历的时候漏掉某些元素。

比如当你删除第1个元素后,后面的元素都往前移动了一位;继续根据索引访问第2个元素时,实际访问的是原来的第3个元素。

因此,这种方式可以用在删除特定的一个元素时使用,但不适合循环删除多个元素时使用。

2、foreach()

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

这种方式的问题在于,删除元素后继续循环会报错误信息ConcurrentModificationException,因为元素在使用的时候发生了并发的修改,导致异常抛出。

但若删除完毕马上使用break跳出,则不会触发报错。

在这里插入图片描述

3、iterator遍历

		Iterator<String> it = list.iterator();
		while(it.hasNext()){
		    String x = it.next();
		    if(x.equals("del")){
		        it.remove();
		    }
		}

iterator方式可以正常的循环及删除。
 但如果用list的remove方法同样会报上面提到的ConcurrentModificationException错误。

总结:

(1)循环删除list中特定一个元素的,可以使用三种方式中的任意一种,但在使用中要注意上面分析的各个问题。

(2)循环删除list中多个元素的,应该使用迭代器iterator方式。

扩展: ArrayList源码

remove()

  /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     *
     * @param index the index of the element to be removed
     * @return the element that was removed from the list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index); // 要删除的元素

        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

        return oldValue;
    }

iterator()源码

	public Iterator<E> iterator() {
        return new Itr();
    }

	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;

        Itr() {}

        。。。
          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();
            }
        }

 		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 boolean hasNext() {
            return cursor != size;
        }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值