可以用for循环直接删除ArrayList的特定元素吗?可能会出现什么问题?怎样解决?
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
可以用for循环直接删除ArrayList的特定元素吗?可能会出现什么问题?怎样解决?的更多相关文章
- Java 删除ArrayList中重复元素,保持顺序
// 删除ArrayList中重复元素,保持顺序 public static List<Map<String, Object>> removeDuplicat ...
- 关于java中ArrayList的快速失败机制的漏洞——使用迭代器循环时删除倒数第二个元素不会报错
一.问题描述 话不多说,先上代码: public static void main(String[] args) throws InterruptedException { List<Strin ...
- 删除ArrayList中的元素
菜鸡重大发现:删除arraylist时,每删除一个元素后面的元素会自动填充 public static void main(String[] args) { List<String> li ...
- 两种方法删除ArrayList里反复元素
方法一: /** List order not maintained **/ public static void removeDuplicate(ArrayList arlList) { HashS ...
- for循环中删除map中的元素,valgrind检测提示error:Invalid read of size 8
#include <iostream> #include <map> using namespace std; class A { public: typedef std::m ...
- PHP删除数组中特定元素
方法一: <?php $arr1 = array(1,3, 5,7,8); $key = array_search(3, $arr1); if ($key !== false) array_sp ...
- **PHP删除数组中特定元素的两种方法array_splice()和unset()
方法一: 复制代码代码如下: <?php$arr1 = array(1,3, 5,7,8);$key = array_search(3, $arr1); if ($key !== false) ...
- ArrayList之foreach循环删除倒数第二个元素,不触发fail-fast机制
今天一朋友问了个问题,对于如下一段代码,运行后会有怎样的结果? public class ArrayListTest { public static void main(String[] args) ...
- Java集合类ArrayList循环中删除特定元素
在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素. 一种错误的方式: <pre name="code" class="java"&g ...
随机推荐
- 【Java/csv】一个CSV文件解析类(转载)
/*下文写得不错,值得学习**/ import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayLis ...
- Hibernate3映射数据类型
1. 在实际开发中需要在hbm文件中使用的type属性值是指定的类型.那 么指定的类型一般的是基于hibernate的类型.2. 当然在实际过程中也可以在hbm文件中指定java类型. publ ...
- 保存图片控件上的图片到本地 出现错误:无法将类型为“System.Windows.Media.Imaging.BitmapFrameDecode”的对象强制转换为类型“System.Windows.Media.Imaging.BitmapImage”。
保存图片控件上的图片到本地 出现错误:无法将类型为“System.Windows.Media.Imaging.BitmapFrameDecode”的对象强制转换为类型“System.Windows.M ...
- JAVA 基础编程练习题13 【程序 13 根据条件求数字】
13 [程序 13 根据条件求数字] 题目:一个整数,它加上 100 后是一个完全平方数,再加上 168 又是一个完全平方数,请问该数是多少? 程序分析:在 10 万以内判断,先将该数加上 100 后 ...
- ubuntu14.04 安装 zoom.us
https://support.zoom.us/hc/en-us/articles/204206269-Getting-Started-on-Linux http://askubuntu.com/qu ...
- 用myeclipse连接MySQL8.0时没有配置jar包
先上测试代码 package testJdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql. ...
- D3画完整柱状图(带坐标轴、标签)
昨天晚上本来打算花一点时间把之前学的柱状图改一下,用CSV文件来替换自定义数据.这一替换可不得了,一晚上就搭进去了,还好今早找到了问题的所在,原因在于我的数据引用出了问题. 现在就来讲解一下如何画一个 ...
- vue-wechat-title动态修改title
在使用Vue制作项目的过程中,发现title没有变化 所以使用vue-wechat-title插件动态修改tilte 一.安装 npm vue-wechat-title --save 二.引入和使用 ...
- Redis二进制反转算法分析
在 redis 源码中 dictScan 算法中用到了用到了非常经典的二进制反转算法,该算法对二进制的反转高效而实用,同时对于理解位运算也有非常大的帮助.先呈现源码: /* Function to r ...
- 阿里云服务器 lnmp安装流程
nginx安装:wget http://nginx.org/download/nginx-1.12.2.tar.gztar zxvf nginx-1.12.2.tar.gzcd nginx-1.12. ...