遍历list集合时同时添加和删除元素

本文探讨了在遍历List时进行元素增删操作的常见问题及解决方案,详细解析了ArrayList与ListIterator的区别,以及Arrays.asList转换的注意事项。

最近码代码时遇到一个坑,遍历一个集合,遍历过程中要删除和新增元素,原代码如下

List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");

Iterator lit = list.iterator();
while (lit.hasNext()) {
    String str = (String) lit.next();
    if (str.equals("a")){
       list.add("add");
       list.remove(str);
    }
}
System.out.println(list);

结果报错:

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
ArrayList.java:901
	at java.util.ArrayList$Itr.next(ArrayList.java:851)

关于这个异常的原因,看了很多文章,基本上解释如下:ArrayList的父类AbstarctList中有一个域modCount,每次对集合进行修改(增添、删除元素)时modCount都会+1,就会造成expectedModCount!=modCount,此时就会抛出java.util.ConcurrentModificationException异常

不过如果使用iterator.remove()方法却是可以成功删除元素,不过还是不能同时新增元素

解决办法如下

使用ListIterator()方法,代码如下:

List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");

ListIterator lit = list.listIterator();
while (lit.hasNext()) {
     String str = (String) lit.next();
     if (str.equals("a")){
         lit.remove();
         lit.add("b");
     }
}
 System.out.println(list);
//结果[b, b, c, d]

总结:

1. ListIterator有add()方法,可以向List中添加对象,而Iterator不能

2. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。

3. ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。

4. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。

因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。

 

再次踩坑:

万万没想到啊,竟再次踩坑,这次是想遍历一个数组转的list,遍历时增删元素,结果又悲剧了,代码如下:

String[] i = {"a","b","c","d"};
List<String> asList = Arrays.asList(i);
ListIterator listIterator = asList.listIterator();
while(listIterator.hasNext()){
	Object next = listIterator.next();
	if("a".equals(next.toString())){
    // listIterator.remove();
    listIterator.add("b");
    }
}
System.out.println(asList);

报错结果:

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.remove(AbstractList.java:161)
AbstractList.java:161
	at java.util.AbstractList$Itr.remove(AbstractList.java:374)

究其原因:

Arrays.asList()创建的是java.util.Arrays.ArrayList,他是Arrays类下的一个内部类

可以看到,他和java.util.ArrayList都继承至AbstractList抽象类,但是他并没有实现add方法和remove方法,当我们调用add方法的时候,他实际调用的是父类AbstractList的add方法

然后就看到throw new UnsupportedOperationException();

再次解决:

把java.util.Arrays.ArrayList转成java.util.ArrayLis

String[] i = {"a","b","c","d"};
ArrayList<String> asList = new ArrayList(Arrays.asList(i));
ListIterator listIterator = asList.listIterator();
while(listIterator.hasNext()){
	Object next = listIterator.next();
	if("a".equals(next.toString())){
        listIterator.remove();
        listIterator.add("b");
	}
}
System.out.println(asList);
//结果[b,b,c,d]

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值