可以用for循环直接删除ArrayList的特定元素吗?可能会出现什么问题?怎样解决?
2024-10-19 17:23:08
for循环直接删除ArrayList中的特定元素是错的,不同的for循环会发生不同的错误,泛型for会抛出 ConcurrentModificationException,普通的for想要删除集合中重复且连续的元素,只能删除第一个。
错误原因:打开JDK的ArrayList源码,看下ArrayList中的remove方法(注意ArrayList中的remove有两个同名方法,只是入参不同,这里看的是入参为Object的remove方法)是怎么实现的,一般情况下程序的执行路径会走到else路径下最终调用faseRemove方法,会执行System.arraycopy方法,导致删除元素时涉及到数组元素的移动。针对普通for循环的错误写法,在遍历第一个字符串b时因为符合删除条件,所以将该元素从数组中删除,并且将后一个元素移动(也就是第二个字符串b)至当前位置,导致下一次循环遍历时后一个字符串b并没有遍历到,所以无法删除。针对这种情况可以倒序删除的方式来避免。
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 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
}
解决方案:用 Iterator:
public static void main(String[] args) { List<String> list = new ArrayList<>(Arrays.asList("a", "b" , "c", "d"));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
if(iterator.next().equals("b")) {
iterator.remove();
}
}
System.out.println(list);
}
输出结果:a, c, d
最新文章
- PDA手持扫描资产标签,盘点完成后将数据上传到PC端,固定资产系统查看盘点结果
- 学习JAVA 安装
- IDisplayTransformation
- mac版photoshop滤镜库报错解法
- bug_ _ android.view.InflateException: Binary XML file line #2: Error inflating class <;unknown
- hdoj 2553 N皇后问题【回溯+打表】
- C#代码生成工具:文本模板初体验 使用T4批量修改实体框架(Entity Framework)的类名
- 性能测试学习 第七课 --loadrunner中JavaVuser脚本的编写
- php开发微信APP支付接口
- 百战程序员——JDBC
- ROS 可视化(一): 发布PointCloud2点云数据到Rviz
- Redis-Migrate-Tool 使用详解
- git reset之后找回本地未提交的代码
- match_parent和fill_parent的区别(转)
- (C++)字符串分割
- Qt5_程序发布
- PHP CURL 抓取失败 自己调试
- 微软自家的.Net下的JavaScript引擎——ClearScript
- Anthem.NET 的回调流程图
- collection包1.1.0都升级了什么功能
热门文章
- LC 722. Remove Comments
- [git]使用Idea创建一个git项目
- Android云端APP
- requestLibrary API
- postgres serial创建自增列
- 20180817周在ubuntu上面使用kettle一些总结
- SrpingMVC通过JSON注入from数据到实体自定义(LocalDateTime,LocalDate,Boolean类型)字段的序列化、反序列化方法
- java数据结构之WeakHashMap
- Python multiprocess模块(下)
- 二叉树实例学习(四)——获取节点的高度函数getHight()