首页游戏资讯任何时候都不要在 for 轮回中删除 List 聚集元素

任何时候都不要在 for 轮回中删除 List 聚集元素

misa2 04-14 2次浏览 0条评论

媒介

起首说结论:无论什么场景,都不要对List利用for轮回的同时,删除List聚集元素,因为那么做就是不合错误的。

阿里开发手册也明白阐明制止利用foreach删除、增加List元素。

准确删除元素的体例是利用迭代器(Iterator),代码如下:

ListString list = new ArrayList();

IteratorString iterator = list.iterator();

while (iterator.hasNext()) {

// 删除元素

iterator.remove();

JDK8后lambda写法:list.removeIf(s - s.contains("a"));

不想晓得为什么不克不及利用for轮回删除List聚集元素的,看完媒介就能够封闭本页面了,想晓得原因的陆续往下看

实例

下面举个实例场景,看一下为什么不克不及利用for轮回。

需求

一个List聚集,元素类型为String,有N个元素,删除那些元素中包罗字符''a''的元素。

假设聚集内容如下:

ListString list = new ArrayList(4);

list.add("a");

list.add("ab");

list.add("abc");

list.add("abcd");

准确谜底

展开全文

先上准确谜底

public static void main(String[] args) {

ListString list = new ArrayList(4);

list.add("a");

list.add("ab");

list.add("abc");

list.add("abcd");

IteratorString iterator = list.iterator();

while (iterator.hasNext()) {

if (iterator.next().contains("a")) {

// 删除元素

iterator.remove();

System.out.println(list);

输出成果为

错误谜底1:通俗for轮回(for-i)

public static void main(String[] args) {

ListString list = new ArrayList(4);

list.add("a");

list.add("ab");

list.add("abc");

list.add("abcd");

for (int i = 0; i list.size(); i++) {

if (list.get(i).contains("a")) {

list.remove(i);

System.out.println(list);

输出成果为

[ab, abcd]

阐发

通俗for轮回遍历List聚集的同时,删除List中的元素是能够运行的代码,但在大大都场景下,不克不及利用那种体例,上边的成果也印证了那一点,固然你的代码不会报错,运行也一般,但在本实例中,那么写就是BUG。

BUG原因:索引为i的元素删除后,后边元素的索引主动向前补位,即本来索引为i+1的元素,变成了索引为i的元素,但是下一次轮回取的索引是i+1,此时你认为取到的是本来索引为i+1的元素,其实取到是本来索引为i+2的元素。

只要每删除一个元素,就会漏掉下一个元素,所以那种体例从逻辑上来说是存在bug的,无论什么需求场景,都不料见用那种体例,因为不成控因素太多(鬼晓得消费情况中他会删掉几元素,同时漏掉几元素)。

既然那么写不报错,那么个别特殊场景确实能够利用那种通俗for轮回删除元素的,好比我们把实例的需求变更一下,改为:一个List聚集,元素类型为String,有N个元素,删除那些元素中包罗字符'a'的元素,假设有持续两个或以上元素包罗'a',那么只删除当前持续元素中的奇数位元素。固然那种场景适用,但仍然不选举,仍是因为太不成控。

错误谜底2:加强for轮回(foreach)

public static void main(String[] args) {

ListString list = new ArrayList(4);

list.add("a");

list.add("ab");

list.add("abc");

list.add("abcd");

for (String str : list) {

if (str.contains("a")) {

list.remove(str);

System.out.println(list);

运行报错:

Exception in thread "main" java.util.ConcurrentModificationException

at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)

at java.util.ArrayList$Itr.next(ArrayList.java:859)

at top.oldmoon.learn.test.ListTest.main(ListTest.java:24)

利用百度翻译能够晓得:Concurrent Modification Exception:并发修改反常

阐发

其实那里没啥好阐发的,间接报错了,你还那么写干嘛?没事找功受吗。。。

能够简单的理解为:foreach就不撑持对聚集中的元素停止增删操做,但是能够修改。

6月份为什么禁止修改头像
血亏!球员仅出场48分钟,俱乐部要付他2450万英镑薪水? 网易LOFTER“AI绘画”风波,给内容社区两个重要启迪
相关内容
发表评论

游客 回复需填写必要信息