-
2021-02-26 08:56:57
今天在做项目时,需要删除List和Set中的某些元素,当时使用边遍历,边删除的方法,却报了以下异常:
ConcurrentModificationException
为了以后不忘记,使用烂笔头把它记录如下:
错误代码的写法,也就是报出上面异常的写法:
Set set = this.getUserDao().getAll(qf).get(0).getActionCheckWorks();
for(CheckWork checkWork : set){
if(checkWork.getState()==1){
set.remove(checkWork);
}
}
注意:使用上面的写法就会报上面的ConcurrenModificationException异常,原因是,集合不可以一边遍历一边删除。
正确的写法如下:
1. 遍历删除List
List list = this.getUserDao().getAll();
Iterator chk_it = list.iterator();
while(chk_it.hasNext()){
CheckWork checkWork = chk_it.next();
if(checkWork.getPlanState()==1){
chk_it.remove();
}
}
2. 遍历删除Set
Set set = this.getUserDao().getAll().get(0).getActionCheckWorks();
Iterator it = set.iterator();
while(it.hasNext()){
CheckWork checkWork = it.next();
if(checkWork.getState()==1){
it.remove();
}
}
以上这篇java中循环遍历删除List和Set集合中元素的方法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
更多相关内容 -
集合Set边遍历边删除
2021-07-01 17:22:37#直接用for遍历删除会抛出异常 #改用Iterator迭代器实现遍历删除 注意:删除时要用iterator的remove方法 下面展示: // A code block Iterator<Element<L>> iterator = repeat.iterator(); while...#直接用for遍历删除会抛出异常
#改用Iterator迭代器实现遍历删除
注意:删除时要用iterator的remove方法下面展示:
// A code block Iterator<Element<L>> iterator = repeat.iterator(); while(iterator.hasNext()) { Element<L> elem = iterator.next(); if(elem.getLabel().equals(label)) { iterator.remove(); k++; } }
// An highlighted block Iterator<Element<L>> iterator = repeat.iterator(); while(iterator.hasNext()) { Element<L> elem = iterator.next(); if(elem.getLabel().equals(label)) { iterator.remove(); k++; } }
-
Java 集合(List、Set)遍历、判断、删除元素时的小陷阱
2021-02-28 08:44:23开发中,常有场景:遍历集合,依次判断是否符合条件,如符合条件则删除当前元素。不知不觉中,有些陷阱,不知你有没有犯。1. 一、漏网之鱼-for循环递增下标方式遍历集合,并删除元素如果你用for循环递增下标方式遍历...开发中,常有场景:遍历集合,依次判断是否符合条件,如符合条件则删除当前元素。
不知不觉中,有些陷阱,不知你有没有犯。
1. 一、漏网之鱼-for循环递增下标方式遍历集合,并删除元素
如果你用for循环递增下标方式遍历集合,在遍历过程中删除元素,你可能会遗漏了某些元素。说那么说可能也说不清楚,看以下示例:
import java.util.ArrayList;
import java.util.List;
public class ListTest_Unwork {
public static void main(String[] args) {
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
System.out.println("Original list : " + list);
String temp = null;
for (int i = 0; i < list.size(); i++) {
temp = list.get(i);
System.out.println("Check for " + temp);
if ("3".equals(temp)) {
list.remove(temp);
}
}
System.out.println("Removed list : " + list);
}
}
日志打印:
Original list : [1, 2, 3, 4, 5]
Check for 1
Check for 2
Check for 3
Check for 5
Removed list : [1, 2, 4, 5]
如日志所见,其中值为4的元素并未经过判断,漏网之鱼。
解决方法为以下两个(但一般不建议我们在遍历中用不是遍历本身的函数删除元素,见下节关于“ConcurrentModificationException”的内容):
1、对于此情况,我一般都从后面开始遍历,以避免问题:
import java.util.ArrayList;
import java.util.List;
public class ListTest_Work {
public static void main(String[] args) {
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
System.out.println("Original list : " + list);
System.out.println();
String temp = null;
for (int i = list.size() - 1; i >= 0; i--) {
temp = list.get(i);
System.out.println("Check for " + temp);
if ("3".equals(temp)) {
list.remove(temp);
}
}
System.out.println("Removed list : " + list);
}
}
2、直接从新创建一个集合,重新摆放,但消耗内存,慎用:
import java.util.ArrayList;
import java.util.List;
public class ListTest_Work2 {
public static void main(String[] args) {
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
System.out.println("Original list : " + list);
System.out.println();
List tempList = new ArrayList();
for (String temp : list) {
System.out.println("Check for " + temp);
if (!"3".equals(temp)) {
tempList.add(temp);
}
}
System.out.println("Removed list : " + tempList);
}
}
2. 二、ConcurrentModificationException异常-Iterator遍历集合过程中用其他手段(或其他线程)操作元素
ConcurrentModificationException是Java集合的一个快速报错(fail-fast)机制,防止多个线程同时修改同一个集合的元素。在用Iterator遍历集合时,如果你用其他手段(非Iterator自身手段)操作集合元素,就会报ConcurrentModificationException。
不信?用Iterator方式或简写的for(Object o : list) {}方式,遍历集合,修改元素时会报异常:
import java.util.ArrayList;
import java.util.List;
public class ListTest2_Unwork {
public static void main(String[] args) {
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
System.out.println("Original list : " + list);
System.out.println();
for (String temp : list) {
System.out.println("Check for " + temp);
if ("3".equals(temp)) {
list.remove(temp);
}
}
System.out.println("Removed list : " + list);
}
}
或
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListTest3_Unwork {
public static void main(String[] args) {
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
System.out.println("Original list : " + list);
System.out.println();
Iterator i = list.iterator();
String temp = null;
while (i.hasNext()) {
temp = i.next();
System.out.println("Check for " + temp);
if ("3".equals(temp)) {
list.remove(temp);
}
}
System.out.println("Removed list : " + list);
}
}
日志:
Original list : [1, 2, 3, 4, 5]
Check for 1
Check for 2
Check for 3
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at ListTest3_Unwork.main(ListTest3_Unwork.java:20)
在删除元素“3”时,会报异常。
对于此情况,需要用iterator的remove方法替代,结果是妥妥的:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListTest3_Work {
public static void main(String[] args) {
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
System.out.println("Original list : " + list);
System.out.println();
Iterator i = list.iterator();
String temp = null;
while (i.hasNext()) {
temp = i.next();
System.out.println("Check for " + temp);
if ("3".equals(temp)) {
i.remove();
}
}
System.out.println("Removed list : " + list);
}
}
延伸个小问题,为什么for(Object o : list) {}方式遍历集合,现象和Iterator方式一样,都会报错呢?
答:这是因为Java的糖语法,“for(Object o : list) {}方式”只是Java语言用“易用性糖衣”吸引你的手段,本质上,它也是Iterator。不信,你写下下面这段程序,反编译看看就清楚了:
package com.nichagil.test.forloop;
import java.util.ArrayList;
import java.util.List;
public class ForTester {
public static void main(String[] args) {
List list = new ArrayList();
list.add("a");
for (String s : list) {
list.remove(s);
System.out.println(s);
}
}
}
package com.nichagil.test.forloop;
import java.util.ArrayList;
import java.util.List;
public class ForTester {
public static void main(String[] args) {
List list = new ArrayList();
list.add("a");
for (String s : list) {
list.remove(s);
System.out.println(s);
}
}
}
反编译后是这样的:
package com.nichagil.test.forloop;
import java.util.ArrayList;
import java.util.Iterator;
public class ForTester {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("a");
Iterator arg2 = list.iterator();
while (arg2.hasNext()) {
String s = (String) arg2.next();
list.remove(s);
System.out.println(s);
}
}
}
package com.nichagil.test.forloop;
import java.util.ArrayList;
import java.util.Iterator;
public class ForTester {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("a");
Iterator arg2 = list.iterator();
while (arg2.hasNext()) {
String s = (String) arg2.next();
list.remove(s);
System.out.println(s);
}
}
}
-
java遍历之数组遍历,list遍历,set遍历,map遍历,stream遍历,Enumeration遍历
2021-09-13 19:41:341._遍历方式 其实遍历的就两种,对象和数组.只是哪个遍历适用于哪个而已 for for增强 foreach 迭代(Iterable) Arrays.toString 2._数组遍历 package com.demo; import java.util.ArrayList; import java.util....1._遍历方式
其实遍历的就两种,对象和数组.只是哪个遍历适用于哪个而已
- for
- for增强
- foreach
- 迭代(Iterable)
- Arrays.toString
2._数组遍历
package com.demo; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; public class demo { public static void main(String[] args) { // 数组遍历方式 String[] arrs = {"a", "b", "c"}; // 第一种方法 for (int i = 0; i < arrs.length; i++) { System.out.println(arrs[i]); } System.out.println("================"); // 第二种方式 for (String str : arrs) { System.out.println(str); } System.out.println("================"); // 第三种方式 System.out.println(Arrays.toString(arrs)); } }
2._list
方法名 描述 void add(int index,E element) 在此集合中的指定位置插入指定的元素 E remove(int index) 删除指定索引处的元素,返回被删除的元素 E set(int index,E element) 修改指定索引处的元素,返回被修改的元素 E get(int index) 返回指定索引处的元素 package com.entify; import java.util.ArrayList; import java.util.Iterator; public class Demo { public static void main(String[] args) { // 对象遍历方式 ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); //第一种方式 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("================"); // 第二种方式 for (String s : list) { System.out.println(s); } System.out.println("================"); // 第三种方式 Iterator<String> iterator = list.iterator(); if (iterator.hasNext()) { System.out.println(iterator.next()); } System.out.println("================"); // 第四种方式 list.forEach(item -> System.out.println(item)); list.forEach(System.out::println); // 第四种方式第二种写法 } }
3._set
A:添加功能 boolean add(E e); boolean addAll(Collection<? extends E> c); B:删除功能 boolean remove(Object o); boolean removeAll(Collection<?> c); void clear(); C:长度功能 int size(); D:判断功能 boolean isEmpty(); boolean contains(Object o); boolean containsAll(Collection<?> c); boolean retainAll(Collection<?> c); E:获取Set集合的迭代器: Iterator<E> iterator(); F:把集合转换成数组 Object[] toArray(); <T> T[] toArray(T[] a); //判断元素是否重复,为子类提高重写方法 boolean equals(Object o); int hashCode();
package com.entify; import java.util.HashSet; import java.util.Iterator; public class Demo { public static void main(String[] args) { HashSet<String> set=new HashSet<String>(); set.add("b"); set.add("b"); set.add("a"); set.add("c"); System.out.println(set);//[a, b, c] // 第一种方式 for (String str : set) { System.out.println(str); } System.out.println("================"); // 第二种方式 Iterator it = set.iterator(); while (it.hasNext()) { String str =(String) it.next(); System.out.println(str); } // 第三种方式 set.forEach(item -> System.out.println(item)); set.forEach(System.out::println); // 第四种方式第二种写法 } }
4._map
方法名 说明 V put(K key,V value) 添加元素 V remove(Object key) 根据键删除键值对元素 void clear() 移除所有的键值对元素 boolean containsKey(Object key) 判断集合是否包含指定的键 boolean containsValue(Object value) 判断集合是否包含指定的值 boolean isEmpty() 判断集合是否为空 int size() 集合的长度,也就是集合中键值对的个数 V get(Object key) 根据键获取值 Set keySet() 获取所有键的集合 Collection values() 获取所有值的集合 Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合 package com.entify; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class Demo { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(2,"b"); map.put(1,"b"); map.put(1,"a"); map.put(4,"b"); map.put(3,"c"); System.out.println(map); // {1=a, 2=b, 3=c, 4=b} // JDK1.4中 // 遍历方法一 hashmap entrySet() 遍历 Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Integer, String> data = it.next(); // 依次获取每行的数据 Object key = data.getKey(); Object value = data.getValue(); System.out.println("key=" + key + " value=" + value); } System.out.println("=============================="); // JDK1.5中,应用新特性For-Each循环 // 遍历方法二 for (Map.Entry<Integer, String> data : map.entrySet()) { Object key = data.getKey(); Object value = data.getValue(); System.out.println("key=" + key + " value=" + value); } System.out.println("===============================11"); // 遍历方法三 hashmap keySet() 遍历 for (Iterator i = map.keySet().iterator(); i.hasNext();) { Object obj = i.next(); System.out.println(obj);// 循环输出key System.out.println("key=" + obj + " value=" + map.get(obj)); } for (Iterator i = map.values().iterator(); i.hasNext();) { Object obj = i.next(); System.out.println(obj);// 循环输出value } System.out.println("===============================11"); // 遍历方法四 treemap keySet()遍历 for (Object o : map.keySet()) { System.out.println("key=" + o + " value=" + map.get(o)); } System.out.println("===============================11"); } }
stream遍历
https://blog.csdn.net/weixin_44797182/article/details/120298300
6._Enumeration遍历
通过Enumeration的源码分析可得,Enumeration有两个方法:
(1)boolean hasMoreElements();//是否还有元素,如果有返回true,否则表示至少含有一个元素
(2)E nextElement();//如果Enumeration枚举对象还有元素,返回对象只能的下一个元素,否则抛出NoSuchElementException异常。简单示例:
public class TestEnumeration{ public static void main(String[] args){ Vector v = new Vector(); v.addElement("Lisa"); v.addElement("Billy"); v.addElement("Mr Brown"); Enumeration e = v.elements();//返回Enumeration对象 while(e.hasMoreElements()){ String value = (String)e.nextElement();//调用nextElement方法获得元素 System.out.print(value); } } }
-
HashMap和List遍历方法及如何遍历删除元素总结
2020-08-25 23:39:24在本篇文章中小编给大家分享了关于HashMap和List遍历方法及如何遍历删除元素知识点总结,需要的朋友们参考下。 -
java中循环遍历删除List和Set集合中元素的方法
2021-03-16 11:16:04package list;import java.util.*;public class Demo {public static void main(String[] args) {List obj = new ArrayList();obj.add("a");...System.out.println("移除前:" + obj.toString())... -
如何边遍历边移除 Collection 中的元素?
2020-03-05 17:40:13边遍历边修改 Collection 的唯一正确方式是使用 Iterator.remove() 方法,如下: Iterator<Integer> it = list.iterator(); while(it.hasNext()){ *// do something* it.remove(); } 如果是List List&... -
对JAVA集合进行遍历删除时务必要用迭代器
2021-02-28 08:40:37java集合遍历删除的方法:1、当然这种情况也是容易解决,实现方式就是讲遍历与移除操作分离,即在遍历的过程中,将需要移除的数据存放在另外一个集合当中,遍历结束之后,统一移除。2、使用Iterator遍历删除。使用... -
【软件构造】关于java中List和Set数据结构不同实现方式和不同遍历方式时间效率的探讨与分析
2021-02-12 21:14:25在java语言中,提供了链表List和集合Set数据类型可供使用,每种数据类型又有多种实现方式可供选择,遍历这些数据结构时存在多种方法,不同的实现方式和不同的遍历方式会产生不同的时间效率,下面重点探讨分析List的... -
Scala之Array / List 数组和 Set 集合的定义,方法,,遍历(4)
2020-09-08 17:17:33一 集合 scala中的集合分两种 ,可变集合和不可变集合 ,不可变集合可以安全的并发访问 . 集合的类主要这以下两个包中 : 1)可变集合包 :scala.... Set不重复集 Map键值映射集 注 :所有的集合都继承自 It... -
Set集合常用方法 && 遍历Set集合的方法
2020-04-13 16:27:56它不按照存储的顺序保存,具有不确定性,也就是说每一次遍历集合出的元素排序不一定相同; 允许使用null元素 LinkedHashSet,特点: 它是HashSet的子类,但它却是按照自然顺序保存的(不是简单的... -
【异常总结】集合(Set)对象遍历遇到的空指针异常
2018-10-31 17:23:42Set&amp;amp;amp;amp;amp;amp;lt;String&amp;amp;amp;amp;amp;amp;gt; groupNames = new TreeSet&amp;amp;amp;amp;amp;amp;lt;&amp;amp;amp;amp;amp;amp;gt;(); …… List&... -
Java HashMap遍历删除
2021-10-12 10:20:53map的迭代删除,和我们常见的list,set不太一样,不能直接获取Iteraotr对象,提供的删除方法也是单个的,根据key进行删除,如果我们有个需求,将map中满足某些条件的元素删除掉,要怎么做呢? 首先初始化一个HashMap... -
遍历对象并且移除属性
2019-09-17 16:00:30for(let i:number = 0, ... if (PlatformHandler.INVALID_SET.indexOf(it)!==-1) { delete props[keys[i]] } } tips 如果还不清楚或者想交个朋友的同学可以微信联系我:qq981145483(备注:csdn fe) -
Set、Map以及List集合的遍历方法
2020-07-17 09:21:55Set、Map以及List集合的几种常用遍历方法代码及运行结果展示 -
《Java测试》关于Map遍历移除在多线程下的测试
2016-10-27 14:45:001.在java 中,for-each只适用于遍历,当要对集合进行操作的时候,就会导致...所以在**移除遍历移除map中的元素时就不能用迭代器**。 所以,就需要for循环进行遍历,大致是这样的 Set<String> setKeys = maps.keySet(); -
Map(java)遍历及其遍历时移除键值对操作
2017-08-29 15:21:00Map(java)遍历及其遍历时移除键值对操作 import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; ... -
Set集合和遍历
2020-03-10 15:24:11Set(集合) 特点:不能有重复的元素,元素没有顺序,元素没有序号,不能通过下标访问。 常用方法 操作元素 add(Object element):在Set集合的尾部添加指定的元素。该方法是从Collection集合继承下来的。 removen... -
Java中集合的遍历与删除
2021-09-01 21:57:15java中集合类型有这样几种:list、set、map,每个类型下面分别对应多个实现类。 list:有序集合,有实现类 ArrayList、LinkedList和 Vector,常用的是第一个,list的特点就是,存进去的数据,顺序不会改变,按照什么... -
map 遍历时 删除元素
2019-08-03 09:23:21import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry...import java.util.Set; public class Test { ... -
python的内置容器(list、set、tuple、dict)概念、使用及遍历方法
2022-04-17 18:56:41#A与B的并集 difference() #差集 discard() #删除元素,如果没有就什么都不做 remove() #删除元素,没有就会异常 pop() #随机移除元素,为空就异常 注:set无下标,所以只能用for来遍历,后面用dict来演示 元祖... -
set循环遍历删除特定元素
2019-10-03 06:39:12使用Iterator迭代器 publicclassDemo{ publicstaticvoidmain(String[]args){ Set<Object>obj=newHashSet<Object>(); obj.add("a"); obj.add("b... -
正确遍历删除List中的元素方法(推荐)
2020-09-01 01:55:49下面小编就为大家带来一篇正确遍历删除List中的元素方法(推荐)。小编觉得挺不错的,在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
java中三种常见集合List,Set,Map的遍历方法
2019-04-30 15:36:26List接口和Set接口继承自Collection接口,可以使用Collection接口中常用的方法,如 add(Object e) // 添加指定对象至当前集合 remove(Object o) // 将指定对象从当前集合移除 isEmpty() // 返回布尔值,判断当前集合... -
UE4 蓝图 实现 数组的边遍历边删除
2016-04-25 11:47:47如下图,最后ArrayTest数组的Length并不为0,foreach节点没有遍历所有元素。解决方法是采用for循环,并且从尾到头遍历。 蓝图的Forloop节点只能从小往大遍历,因此可以用if语句的循环来代替,实现如下。最后输出...