JAVA中循环删除list中元素
JAVA中循环遍历list有三种方式for循环、增强for循环(也就是常说的foreach循环)、iterator遍历。
1、for循环遍历list
for(int i=0;i<list.size();i++){
if(list.get(i).equals("del"))
list.remove(i);
}
这种方式的问题在于,删除某个元素后,list的大小发生了变化,而你的索引也在变化,所以会导致你在遍历的时候漏掉某些元素。比如当你删除第1个元素后,继续根据索引访问第2个元素时,因为删除的关系后面的元素都往前移动了一位,所以实际访问的是第3个元素。因此,这种方式可以用在删除特定的一个元素时使用,但不适合循环删除多个元素时使用。
2、增强for循环
for(String x:list){
if(x.equals("del"))
list.remove(x);
}
这种方式的问题在于,删除元素后继续循环会报错误信息ConcurrentModificationException,因为元素在使用的时候发生了并发的修改,导致异常抛出。但是删除完毕马上使用break跳出,则不会触发报错。
3、iterator遍历(推荐)
Iterator<String> it = list.iterator();
while(it.hasNext()){
String x = it.next();
if(x.equals("del")){
it.remove();
}
}
这种方式可以正常的循环及删除。但要注意的是,使用iterator的remove方法,如果用list的remove方法同样会报上面提到的ConcurrentModificationException错误。
总结:
(1)循环删除list中特定一个元素的,可以使用三种方式中的任意一种,但在使用中要注意上面分析的各个问题。
(2)循环删除list中多个元素的,应该使用迭代器iterator方式。
---20200427↓---
4.使用Java 8中提供的filter过滤
Java 8中可以把集合转换成流,对于流有一种filter操作, 可以对原始 Stream 进行某项测试,通过测试的元素被留下来生成一个新 Stream。
List<String> userNames = new ArrayList<String>() {{
add("Hollis");
add("hollis");
add("HollisChuang");
add("H");
}};
userNames = userNames.stream().filter(userName -> !userName.equals("Hollis")).collect(Collectors.toList());
System.out.println(userNames);//[hollis, HollisChuang, H]
5.使用增强for循环其实也可以
如果,我们非常确定在一个集合中,某个即将删除的元素只包含一个的话, 比如对Set进行操作,那么其实也是可以使用增强for循环的,只要在删除之后,立刻结束循环体,不要再继续进行遍历就可以了,也就是说不让代码执行到下一次的next方法。
List<String> userNames = new ArrayList<String>() {{
add("Hollis");
add("hollis");
add("HollisChuang");
add("H");
}};
for (String userName : userNames) {
if (userName.equals("Hollis")) {
userNames.remove(userName);
break;
}
}
System.out.println(userNames);//[hollis, HollisChuang, H]
6.使用fail-safe的集合类
在Java中,除了一些普通的集合类以外,还有一些采用了fail-safe机制的集合类。这样的集合容器在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。
由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发ConcurrentModificationException。
ConcurrentLinkedDeque<String> userNames = new ConcurrentLinkedDeque<String>() {{
add("Hollis");
add("hollis");
add("HollisChuang");
add("H");
}};
for (String userName : userNames) {
if (userName.equals("Hollis")) {
userNames.remove();
}
}
System.out.println(userNames);//[hollis, HollisChuang, H]
基于拷贝内容的优点是避免了ConcurrentModificationException,但同样地,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改。
JAVA中循环删除list中元素的更多相关文章
- Java中循环删除list中元素的方法总结
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后在今天使用的时候发现报错了,然后去科普了一下,发现这是一个误区.下面我们来一起看一下. Java中循环遍 ...
- JAVA中循环删除list中元素的方法总结【转】
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接跳至文末 ...
- JAVA中循环删除list中元素的方法总结(同上篇)
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接跳至文末 ...
- java中循环删除list中元素的方法
重点哈 印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接 ...
- python中循环删除列表中元素时的坑!
循环删除列表中元素时千万别用正序遍历,一定要用反序遍历! 废话不多说,先上案例代码: def test(data): for i in data: data.remove(i) return data ...
- for循环删除list中多个元素出现的误区
错误的做法是: for(int i= 0;i<list.size();i++) 因为在你删除元素的同时list.size()也在变小,这样就会照成越界. 正确做法:因为要删除list里面的多个的 ...
- JS实现循环删除数组中元素的方法介绍
这篇文章主要给大家介绍了关于Javascript循环删除数组中元素的几种方法,文中给出了详细的示例代码供大家参考学习,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧. 本文主要跟大家分享了 ...
- python中如何删除列表中的所有元素
今天写代码的时候遇到一个小问题,Python中要删除列表中的所有元素.Python本身就提供了pop.remove.del这些删除的函数.我想着用循环实现,结果很麻烦.几番周折上了stackoverf ...
- JS中如何删除某个父元素下的所有子元素?
JS中如何删除某个父元素下的所有子元素?这里我介绍几种方法: 1.通过元素的 innerHTML 属性来删除 这种方式我觉得是最有方便的,直接找到你想要的父元素,直接令其 element.innerH ...
随机推荐
- Codeforces 1154C Gourmet Cat
题目链接:http://codeforces.com/problemset/problem/1154/C 题目大意: 主人有一只猫.周一&周四&周日:吃鱼周二&周六:吃兔子周三 ...
- vscode運行vue和html
html 选中html文件,右键选择view in broswer.
- vue之v-for使用说明
demo.html <!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/19 ...
- LODOP 获取打印设计代码不带INIT初始化语句
前面的博文生成JS代码模版和文档式模版,生成的是带初始化语句的模版,如果想要打印多个,可以循环多个任务,什么是一个任务,可查看本博客相关博文:Lodop打印语句最基本结构介绍(什么是一个任务)一个任务 ...
- HTML中文本过长时自动隐藏末尾部分或中间等任意部分
一. 一般情况下,HTML字符串过长时都会将超过的部分隐藏点,方法如下: 设置CSS: .ellipsis-type{ max-width: 50px; ...
- 4.namespace
命名空间( namespace)是 Linux 内核的一个强大特性,为容器虚拟化的实现带来极大便 利. 利用这一特性,每个容器都可以拥有自己单独的命名空间,运行在其中的应用都像是在 独立的操作系统环境 ...
- controller层负责创建类传递类给service;service层负责逻辑编写调用dao层 将编写后的类传递到dao层,保证事务的正确性;dao层负责数据的持久化
controller层负责创建类传递类给service:service层负责逻辑编写调用dao层 将编写后的类传递到dao层,保证事务的正确性:dao层负责数据的持久化
- git使用常见问题
1.git branch使用,创建新的分之后做修改后,其他分支也被同步修改 问题: 原项目在 master 分支,执行下面的操作: git branch test git checkout tes ...
- Nginx IP地址透传
L:119
- Codeforces Round #419 Div. 1
A:暴力枚举第一列加多少次,显然这样能确定一种方案. #include<iostream> #include<cstdio> #include<cmath> #in ...