List的remove()方法详解
https://blog.csdn.net/anxin_hw/article/details/128312846
一、错误使用场景
1、普通for循环遍历List删除指定元素,list.remove(index)
示例:将姓张的名字移除掉
1 2 3 4 5 6 7 8 9 10 11 | List<String> nameList = new ArrayList<>(Arrays.asList( "张三" , "李四" , "王五" , "赵六" )); nameList.add( "张七" ); nameList.add( "张八" ); for ( int i = 0; i < nameList.size(); i++) { String name = nameList. get (i); System. out .println( "当前遍历对象===" +name); if (name.startsWith( "张" )) { nameList.remove(i); } } System. out .println(nameList); |
输出结果:
【李四】【张八】遍历被跳过,【张八】没有被成功移除
原因分析:
List调用remove(index)方法后,会移除index位置上的元素,之后的所有元素依次前移,当移除完【张三】时,【李四】变成了数组的第一位,此时的索引应该要index-1才能获取到【李四】。所以每移除一个元素时就需要把index-1,否则原来索引为index+1的元素就无法遍历到。
2、foreach遍历List删除元素
示例:同上
1 2 3 4 5 6 7 8 9 10 | List<String> nameList = new ArrayList<>(Arrays.asList( "张三" , "李四" , "王五" , "赵六" )); nameList.add( "张七" ); nameList.add( "张八" ); for (String name : nameList) { System. out .println( "当前遍历对象===" +name); if (name.startsWith( "张" )) { nameList.remove(name); } } System. out .println(nameList); |
输出结果:
原因分析:
foreach循环实际上是迭代,使用list.remove(item)方法后,list 对象的modCount值进行了修改,而 list对象的迭代器中的expectedModCount值没有修改,所以抛出了异常
3、直接使用list.remove(object)
示例: 将张三从数组中移除
1 2 3 4 5 | List<String> nameList = new ArrayList<>(Arrays.asList( "张三" , "李四" , "王五" , "赵六" )); nameList.add( "张三" ); nameList.add( "张三" ); nameList.remove( "张三" ); System. out .println(nameList); |
输出结果:[李四, 王五, 赵六, 张三, 张三]
原因分析:
list.remove(object)的逻辑和list.remove(index)大致相同:元素依次遍历,数组中存在与入参对象相等的元素就移除,之后的所有元素依次前移,返回true,若不存在与入参相等的元素,返回false。
二、正确使用方法
1、 使用list.removeIf()方法
removeIf()的入参是一个过滤条件,用来判断需要移除的元素是否满足条件。
原理:方法中设置了一个removeSet,把满足条件的元素索引坐标都放入removeSet,然后统一对removeSet中的索引进行移除
示例:将姓张的名字移除掉
1 2 3 4 5 | List<String> nameList = new ArrayList<>(Arrays.asList( "张三" , "李四" , "王五" , "赵六" )); nameList.add( "张七" ); nameList.add( "张八" ); nameList.removeIf(o->o.startsWith( "张" )); System. out .println(nameList); |
输出结果:[李四, 王五, 赵六]
2、使用迭代器Iterator移除元素
迭代器是一个链表,直接使用remove操作不会出现问题
示例:同上
1 2 3 4 5 6 7 8 9 10 | List<String> nameList = new ArrayList<>(Arrays.asList( "张三" , "李四" , "王五" , "赵六" )); nameList.add( "张七" ); nameList.add( "张八" ); Iterator<String> iterator = nameList.iterator(); while (iterator.hasNext()) { if (iterator.next().startsWith( "张" )) { iterator.remove(); } } System. out .println(nameList); |
输出结果:[李四, 王五, 赵六]
3、使用list.removeAll()方法
定义一个需要移除的数组,for循环内将需要移除的元素收集在定义的数组中,for循环结束后直接removeAll()
示例:同上
1 2 3 4 5 6 7 8 9 10 11 | List<String> nameList = new ArrayList<>(Arrays.asList( "张三" , "李四" , "王五" , "赵六" )); nameList.add( "张七" ); nameList.add( "张八" ); List<String> removeList = new ArrayList<>(); for (String name : nameList) { if (name.startsWith( "张" )) { removeList.add(name); } } nameList.removeAll(removeList); System. out .println(nameList); |
输出结果:[李四, 王五, 赵六]
4、倒序遍历元素然后删除
正序删除元素会移位那我们转变思维倒序遍历
示例:
1 2 3 4 5 6 7 8 9 10 11 | List<String> nameList = new ArrayList<>(Arrays.asList( "张三" , "李四" , "王五" , "赵六" )); nameList.add( "张七" ); nameList.add( "张八" ); for ( int i = nameList.size() - 1; i >= 0; i--) { String name = nameList. get (i); System. out .println( "当前遍历对象===" + name); if (name.startsWith( "张" )) { nameList.remove(i); } } System. out .println(nameList); |
输出结果:
三、总结
1、使用普通for循环删除元素时需要注意索引会变化的问题
2、list删除元素时建议使用迭代器Iterator或者removeIf()方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了