可以用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 ...
随机推荐
- vscode 记住git用户密码
一.选中文件-->首选项-->设置,搜索git,在setting.json中添加 "git.path":"/bin/git.exe" 二.git b ...
- go module 使用举例
go语言中,从1.11开始,引入module,进行版本管理. 通过使用module,工程目录的位置不用必须放在GOPATH下. 本文介绍 module的使用. 下文中用的Go版本是1.13. 1. g ...
- Laravel中Session的使用
以file为示例 1.Http request session方法$request->session()->put('key1','value1');echo $request->s ...
- 在jsp页面如何获得url参数
方法一:当一个url过来时,如:http://localhost:8080/pro/demo/hello.jsp?name=john,在hello.jsp页面,我们可以这样得到name的值: < ...
- dede不同栏目调用不同banner图的方法
用顶级栏目ID 方法: <img src="{dede:global.cfg_templets_skin/}/images/{dede:field.typeid function=&q ...
- docker MySQL官方版本使用记录
docker MySQL官方版本使用记录 使用记录 拉取官方镜像:docker pull mysql 运行镜像:docker run --name mysql -p 3306:3306 -e MYSQ ...
- 爬虫实现51job谁看过我的简历多条记录功能
默认情况下51job只能看到最近一条记录,查看更多记录需要付费. 本文利用爬虫定时抓取记录,并追加写入到文本的方式获取完整的记录信息. import requests from bs4 import ...
- C学习笔记-流程控制
常用的流程图符号 起止框用于表示流程的开始或结束: 输入/输出框用平行四边形表示,在平行四边形内可以写明输入或输出的内容: 判断框用菱形表示,它的作用是对条件进行判断,根据条件是否成立来决定如何执行后 ...
- Linux命令---ln、readlink
ln 无参数--------创建硬链接 -s -------------创建软链接 用法:ln [option] 源文件 目标文件 ln test.txt test_hard.txt 只有在同 ...
- (补发)学pythion的第二天
所学知识点: if语句的使用 在Python中,要构造分支结构可以使用if.elif和else关键字.所谓关键字就是有特殊含义的单词,像if和else就是专门用于构造分支结构的关键字,很显然你不能够使 ...