秦皇岛 免费建网站,凡科互动游戏可以作弊码,自己做网站要买域名吗,wordpress 内容更新插#xff1a; 前些天发现了一个巨牛的人工智能学习网站#xff0c;通俗易懂#xff0c;风趣幽默#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈#xff0c;越努力越幸运#xff0c;大家一起学习鸭~~~ 在实际的业务开发中#xff0c;容器的遍历可以说是非… 插 前些天发现了一个巨牛的人工智能学习网站通俗易懂风趣幽默忍不住分享一下给大家。点击跳转到网站。 坚持不懈越努力越幸运大家一起学习鸭~~~ 在实际的业务开发中容器的遍历可以说是非常非常常见的场景了遍历删除呢用的机会也比较多那么有哪几种删除元素的方法呢你用对了吗~ 本文循序渐进先说几种容易出问题的方法再引出几种比较可靠的方法~
首先初始化一个数组用于后面的事例演示:
ListInteger list new ArrayList();
for (int i 1; i 5; i) {if(i2) {//i2时添加两次用于后面的测试list.add(i); list.add(i); }else {list.add(i); }
}方法一for-each循环删除结果抛出异常
for (String id : list){if (id.contains(3)) {list.remove(id); }}运行上面的代码抛出如下异常 抛出异常的根本原因在于for-each是使用Iterator来实现遍历的调用ArrayList.remove()方法会将modCount1而Iterator内部的expectedModCount确没有更新这样在进行下次循环时调用Iterator.next()会对modCount和expectedModCount进行比较不一致就会抛出ConcurrentModificationException异常。 当删除完元素后进行下一次循环时会调用下面源码中Itr.next()方法获取下一个元素会调用checkForComodification()方法对ArrayList进行校验判断在遍历ArrayList是否已经被修改由于之前对modCount1而Iterator中的expectedModCount还是初始化时ArrayList.Itr对象时赋的值所以会不相等然后抛出ConcurrentModificationException异常。
方法二普通for循环正序删除结果会漏掉对后一个元素的判断
for (int i 0; i list.size(); i) {if (2equals(list.get(i) )) {//2是要删除的元素list.remove(i);//解决方案: 加一行代码i i - 1; 删除元素后下标减1}System.out.println(当前List是list.toString());
}
//原ArrayList是[1, 2, 3, 3, 4]
//删除后是[1, 2, 3, 4] 少删除了一个元素2
可以看到少删除了一个元素2.
原因在于调用remove删除元素时remove方法调用System.arraycopy()方法将后面的元素移动到前面的位置也就是第二个num:2会移动到数组下标为2的位置而在下一次循环时i1之后i会为2不会对数组下标为1这个位置进行判断所以这种写法在删除元素时被删除元素a的后一个元素b会移动a的位置而i已经加1会忽略对元素b的判断所以如果是连续的重复元素会导致少删除。 **解决方案:**可以在删除元素后执行ii-1使得下次循环时再次对该数组下标进行判断。
方法三普通for循环倒序删除结果正确删除 for (int i list.size() -1 ; i0; i--) {if (list.get(i).equals(2)) {list.remove(i);}System.out.println(当前list是list.toString());
}//原ArrayList是[1, 2, 3, 3, 4]
//删除后是[1, 3, 4]这种方法可以正确删除元素因为调用remove删除元素时remove方法调用System.arraycopy()将被删除元素a后面的元素向前移动而不会影响元素a之前的元素所以倒序遍历可以正常删除元素。
方法四Iterator遍历使用ArrayList.remove()删除元素结果抛出异常
IteratorInteger iterator list.iterator();
while (iterator.hasNext()) {Integer value iterator.next();if (value.equals(3)) {//3是要删除的元素list.remove(value);}System.out.println(当前list是list.toString());
}
第4种方法其实是第1种方法在编译后的代码所以第四种写法也会抛出ConcurrentModificationException异常。这种需要注意的是每次调用iterator的next()方法会导致游标向右移动从而达到遍历的目的。所以在单次循环中不能多次调用next()方法不然会导致每次循环时跳过一些元素.
方法五 Iterator遍历使用Iterator的remove删除元素结果正确删除
IteratorInteger iterator list.iterator();
while (iterator.hasNext()) {Integer value iterator.next();if (value.equals(3)) {//3是需要删除的元素iterator.remove();}
}方法5可以正确删除元素。
跟第1种和第4种方法的区别在于是使用**iterator.remove();**来移除元素而在remove()方法中会对iterator的expectedModCount变量进行更新所以在下次循环调用iterator.next()方法时expectedModCount与modCount相等不会抛出异常。
方法六jdk8 流方式 list.removeIf 结果正确删除
jdk8 推荐下面这种写法简洁明了
list.removeIf(s - s.contains(3));结论
在list遍历中不要使用list.remove(), 容易出问题 推荐使用方法五的iterator.remove()或者方法六的 list.removeIf().