List集合删除元素,该怎么删除?

本文通过示例代码详细对比了Java中直接使用ArrayList的remove()方法与使用Iterator的remove()方法删除元素的不同效果及原因,特别是针对连续相同元素删除的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.zz.web.controller;

import java.util.ArrayList;
import java.util.Iterator;

public class TestDelList {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        ArrayList<String> lists = new ArrayList<String>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("b");
        list.add("b");
        list.add("e");
        list.add("b");
        list.add("d");
        lists.addAll(list);
        //此处先使用list的remove()方法
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).equals("b")) {
                list.remove(i);
            }
            System.out.println(list.toString() + list.size());
        }
        //下面使用Iterator的remove()方法是跟上面做一个对比
        Iterator<String> it = lists.iterator();
        while (it.hasNext()) {
            String string = (String) it.next();
            if (string.equals("b")) {
                it.remove();
            }
            System.out.println("w" +lists.toString()+ lists.size());
        }
    }
}
运行后的结果是:
[a, b, c, b, b, e, b, d]8
[a, c, b, b, e, b, d]7
[a, c, b, e, b, d]6
[a, c, b, e, b, d]6
[a, c, b, e, d]5
w[a, b, c, b, b, e, b, d]8
w[a, c, b, b, e, b, d]7
w[a, c, b, b, e, b, d]7
w[a, c, b, e, b, d]6
w[a, c, e, b, d]5
w[a, c, e, b, d]5
w[a, c, e, d]4
w[a, c, e, d]4

大家发现没有,如果使用list的remove()方法,想要把list集合里的b元素删除,会导致上述的情况发生(该情况是需要删除的元素都是相邻的元素,用代码解释就是list.get(i).equals(list.get(i+1))==true, 这样在移除b(i=3时)元素的时候该节点都被删除了,后面的元素就会往前移动一位,当循环下一个i=2的时候list.get(4)的值不是b元素了而是e元素);而使用迭代器Iteratoer去遍历该list集合用迭代器的remove方法就不会导致该问题出现
为什么用list的remove()就不可以呢?我找了源码才发现它实际上调用的是另一个方法:

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; 
    }

看出来什么了吗?有一个数组复制的方法:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
src:源数组;
srcPos:源数组要复制的起始位置;
dest:目的数组;
destPos:目的数组放置的起始位置;
length:复制的长度。
注意:src and dest都必须是同类型或者可以进行转换类型的数组。

由此看出为什么会前移一位吗?
(其实最主要的原因不在这里,最主要的原因是其中有一个计数器modCount还有期望被修改次数expectedModCount),当使用list.remove()的时候,该modCount会加1而expectedModCount是0,Iterator.remove()却不会,是因为在Iterator的remove方法中它将modCount=expectedModCount)具体见下面的文章,我就不一一解释了。仔细看完保证你有收获!

更多详情请参照我参考的关于list和Iterator的remove方法区别文章Blog地址 ↓↓↓↓↓

http://www.cnblogs.com/dolphin0520/p/3933551.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值