精华内容
下载资源
问答
  • 一开始代码如下,执行后在for循环那一行报错空指针,但是上方已经判断了list不为null,不为空 private List<InstallRow> list; if (list!= null && !list.isEmpty()) { for(InstallRow installRow ...

    一开始代码如下,执行后在for循环那一行报错空指针,但是上方已经判断了list不为null,不为空

    private List<InstallRow> list;
    if (list!= null && !list.isEmpty()) {
        for(InstallRow installRow : list) {        
        if(installRow.getUniqueIndexHashValue().equals(uniqueIndexHashValue)) {
            datas.remove(installRow);
        }
    }

     原因是因为list再遍历的过程中被删掉元素导致原先的下一个值找不到

    解决方法可以为 删除完毕马上使用break跳出,这样便不会抛出错误

    private List<InstallRow> list;
    if (list!= null && !list.isEmpty()) {
        for(InstallRow installRow : list) {        
        if(installRow.getUniqueIndexHashValue().equals(uniqueIndexHashValue)) {
            datas.remove(installRow);
            break;
        }
    }

    但是这种方式只适合删掉某个值,而不是某些值的情况

     

    如果需要删除某些值,就不能使用增强for循环,可以使用iterator遍历

    Iterator<String> it = list.iterator();
    while(it.hasNext()){
       if(installRow.getUniqueIndexHashValue().equals(uniqueIndexHashValue)) {
           datas.remove(installRow);
       }
    }

     

    展开全文
  • 不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用Iterator 方式,如果并发操作,需要对 Iterator 对象加锁 正例: List<String> list = new ArrayList<>(); list.add("1"); list....

    笔者在阅读阿里巴巴Java开发手册时看到这样一段话:

    不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用Iterator 方式,如果并发操作,需要对 Iterator 对象加锁
    正例:

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
    	String item = iterator.next();
    	if (删除元素的条件) {
    		iterator.remove();
    	}
    }
    

    反例:

    for (String item : list) {
    	if ("1".equals(item)) {
    		list.remove(item);
    	}
    }
    

    说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结果吗?

    笔者疑惑,什么意思,难道不是所有的增强for删除元素都会报错吗?记得是modCount != expectedModCount的时候会报错呀

    于是笔者实现了一下,发现…

            List<String> list = new ArrayList<>();
            list.add("1");
            list.add("2");
    
            for (String item : list) {
                if ("1".equals(item)) {
                    list.remove(item);
                }
            }
            System.out.println(list);
    

    发现居然…
    在这里插入图片描述
    一条小绿条震惊了我
    在这里插入图片描述
    然后我执行第二套代码,也就是把1换成2

            List<String> list = new ArrayList<>();
            list.add("1");
            list.add("2");
    
            for (String item : list) {
                if ("2".equals(item)) {
                    list.remove(item);
                }
            }
            System.out.println(list);
    

    在这里插入图片描述
    呼~报错了,是我满意的结果。

    于是,我决定debug一下发生了什么,第一套代码为什么不会报错呢。

    首先进到remove方法
    在这里插入图片描述
    很合理,进到fastRemove方法了
    在这里插入图片描述
    modCount++,移动元素,让空出的位置值null让GC清理,很合理,1 被删除了。
    在这里插入图片描述
    然后回来,return true,进行下一个遍历。增强for是会用ArrayList的内部类,来判断是否有下一个元素,cursor是一个游标,判断是否遍历到头了。在这里插入图片描述
    可以看到,由于刚才已经删除了“1”,所以size为1,而cursor由于是到索引1了,haxNext的判断游标与长度是相等的,在他看来遍历结束了,返回false。于是遍历结束,这样还没进入到modCount和expectedModCount的比较,遍历就已经退出~

    让我们再来看看第二套代码

    由于第一个值是“1”,不相等,所以直接进入第二个循环

    在这里插入图片描述
    跟前面一样,会用ArrayList的内部类判断是否遍历结束
    在这里插入图片描述
    这里游标为1,size为2,所以不相等,为true

    接下来是调用next方法,这个方法依旧是ArrayList的内部类Itr持有
    在这里插入图片描述
    进入checkForComodification方法
    在这里插入图片描述
    可以看到,由于之前没有删除操作,所以这一步是ok的,不会报错。

    继续走next剩余的方法,没有问题。
    在这里插入图片描述

    接下来因为相等了,执行remove方法在这里插入图片描述
    在这里插入图片描述
    执行fastRemove方法,modCount的值变化
    在这里插入图片描述
    然后增强for循环继续
    在这里插入图片描述
    发现hasNext依旧成立,因为游标cursor为2,而长度为1
    于是执行next方法,首先执行checkForComodification
    在这里插入图片描述
    modCount不等于expectedModCount,抛出异常
    在这里插入图片描述

    总结:
    原来如此,代码1之所以没有报错,原来是因为它没有进入到modCount和expectedModCount的判断就结束了。但是只要我们明确不能在增强for循环删除、插入元素,还是ok的~。

    果然,要了解底层,还是得自己看看源码才知道。

    展开全文
  • 在集合中使用增强for循环通过if判断元素是否满足条件,然后操作删除该元素时报错的坑; 在使用增强for循环时代码: List<Integer> list = new ArrayList<>(); list.add(1); list.add(1); list.add(2...

    在集合中使用增强for循环通过if判断元素是否满足条件,然后操作删除该元素时报错的坑;

    在使用增强for循环时代码:

            List<Integer> list = new ArrayList<>();
            list.add(1);
            list.add(1);
            list.add(2);
            list.add(1);
            System.out.println(list + "-----------------");
    
            for (Integer a : list) {
                if (a != 100) {
                    list.remove(a);
                } else {
                    System.out.println("测试删除后是否还能继续");
                }
            }
            System.out.println(list + "===========");
        }
    

    运行结果
    在这里插入图片描述

    使用Iterator迭代器时,代码如下:

    List<Integer> list = new ArrayList<>();
            list.add(1);
            list.add(1);
            list.add(2);
            list.add(1);
            
            System.out.println(list + "--------------");
            Iterator<Integer> iterator = list.iterator();
            while (iterator.hasNext()) {
                Integer a = iterator.next();
                if (a != 1) {
                    iterator.remove();
                } else {
                    System.out.println("测试删除后是否还能继续");
                }
            }
            System.out.println(list + "===========");
    
        }
    

    结果如下:
    在这里插入图片描述
    虽然增强for循环也是迭代器的一种体现,是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的,底层使用的也是迭代器,使用for循环的格式,简化了迭代器的书写。但是在遍历过程中,不能对集合中的元素进行增删操作。

    展开全文
  • 增强for循环删除

    2020-07-10 17:48:54
    通过反编译文件发现增强for循环底层实现是迭代器 源码追踪 cursor:迭代器游标,初始值为0,每迭代一次就会+1; lastRet:最后一个元素的索引值,若不存在返回-1; expectedModCount:预期修改次数,在初始化时...

    在这里插入图片描述

    在这里插入图片描述

    疑问:为什么删除倒数第二个不报错

    通过反编译文件发现增强for循环底层实现是迭代器

    源码追踪
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    cursor:迭代器游标,初始值为0,每迭代一次就会+1;
    lastRet:最后一个元素的索引值,若不存在返回-1;
    expectedModCount:预期修改次数,在初始化时就已经被赋为modCount

    ① 调用hasNext(),判断是否还有下一个元素,通过判断游标和list长度来判断,如果不一致,则代表还有下一个元素。
    ② 调用next(),此时会走checkForComodification(),去校验实际修改次数和预期修改次数是否一致,如果不一致,则抛出异常,触发fail-fast机制;(fail-fast 机制是java集合中的一种错误机制,快速失败)

    cursor->0 cursor->1
    next->a next->b remove->modCount->5,size->3
    cursor->2
    next->checkForComodification,modCount(5) != exceptedModCount(4),fail-fast

    cursor->0 cursor->1 cursor->2
    next->a next->b next->c remove->modeCount->5,size->3
    cursor->3
    next->hasNext(),cursor(3) == size(3) break;

    总结:
    hasNext()判断cursor和size是否一致,一致就break,删除到倒数第二个的时候刚好一致,所以不会接着走next(),next()会判断modCount和expectedModCount是否一致,不一致就fail-fast,所以如果不是删除倒数第二个出现特殊的cursor=size的话,删除其他就会fail-fast

    如何解决fail-fast:调用迭代器内部的remove,而不是AarrayList的remove;

    展开全文
  • foreach 是 Java 中的一种语法,几乎每一种语言都有一些这样的语法糖来方便程序员进行开发,编译期间以特定的字节码或特定的方式来对这些语法进行处理。...for(元素类型 ele : 数组名/Iterable 实...
  • ``` Circlelist[] tempArr = new Circlelist[radix]; // for (Circlelist tempList : tempArr) { ...**为什么第一个增强for循环不能对tempArr数组的每个成员进行初始化,而第二个普通的for循环却可以**
  • 一、增强for循环 1. 三种常用for循环 // 普通for循环遍历 for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i) + ","); } // 迭代器循环遍历 Iterator iterator = list.iterator(); while...
  • java中在增强for循环为什么不能增删集合呢?一个循环迭代,跟集合的增删改没什么关系。修改集合不是for去做的。for只管循环迭代,你在循环里边修改集合,改变集合的长度,顺序对循环都有影响
  • 增强for循环

    2021-05-23 20:21:23
    增强for循环一、什么是增强for循环?二、使用步骤1.引入库2.读入数据总结 一、什么是增强for循环增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合。其内部原理是一个...
  • 1、目的:简化数组和Collection集合的遍历2、格式: for(元素数据类型 变量 : 数组或者Collection集合){ 使用变量即可,该变量就是元素 }3、数组,集合存储元素用增强for遍历1)数组int[] arr = {11,22,33,44,55}...
  • for循环分为两种:一种为普通for循环,一种为增强for循环(也就是foreach循环) 区别: 1)任何循环都能用普通for循环运行,但不一定能用增强for循环,也就是增强for循环的使用范围要小。 2)增强for循环内部其实是...
  • for循环与增强for循环

    千次阅读 2019-02-26 00:00:58
    @for循环与增强for循环 for与增强for循环的对比 for循环分为两种: 第一种为普通的for循环 这种for循环通常需要三个步骤即 for(初始表达式;条件表达式;递增表达式)有时候递增表达式也可以省去,一般是在使用...
  • 现在我想删除前五个,要求用一次for循环,问问该怎么做到?   我当时想这道题肯定没有那么简单,应该不是常规思路可以解决的。于是,我给出的我的解决思路是,开辟一个集合把后五个元素加入其中,然后覆盖掉原来...
  • 相信for循环对大家来说一定很不陌生,毕竟不管是初学者还是资深老鸟对于for循环的使用都应该是较为频繁的,那么不知道大家对于增强for循环是否同样熟悉呢? 首先增强for循环和iterator遍历的效果是一样的,也就说...
  • for循环之增强for循环

    2020-11-05 17:46:36
    增强for循环,属于for循环的一种用法,不同的是增强型for只能用来取值,却不能用来修改数组里面的值 //对数组进行遍历 int a[] = new int[]{1,2,3,4,5}; //常规for循环遍历 for int(i = 0; i < a.length; i++) ...
  • 普通for循环语法: for (int i = 0; i < integers.length; i++) { System.out.println...增强for循环语法: for(Integer in : integers){ System.out.println(in); } 今天我们通过使用两种for循...
  • java 普通for循环与增强for循环的性能对比

    千次阅读 多人点赞 2019-01-23 15:35:18
    有些人用的是增强for循环, 它们之间有什么区别?应该在什么时候使用这两种循环了? ==========语法格式========== 普通for循环语法: for (int i = 0; i &lt; integers.length; i++) { System.out....
  • 有时会遇到这样的业务需要,在 for 循环删除列表元素,比如下面的例子。 List<User> userList = userDao.getUserList(); for(int i = 0; i < userList.size(); i++){ User user = userList.get(i); ...
  • 增强for循环的用法

    2020-09-06 17:20:00
    一、增强for循环 增强for循环的作用:简化迭代器的书写格式。...增强for循环的缺点:增强for循环和iterator遍历的效果是一样的,也就说增强for循环的内部也就是调用iteratoer实现的,但是增强for循环有些缺点,例...
  • 关于增强for循环的用法

    万次阅读 多人点赞 2016-12-02 12:50:07
    一、增强for循环增强for循环的作用: 简化迭代器的书写格式。(注意:增强for循环的底层还是使用了迭代器遍历。) 增强for循环的适用范围: 如果是实现了Iterable接口的对象或者是数组对象都可以使用增强for循环。 ...
  • 什么时候使用普通for循环,什么时候使用增强for循环 首先,增强for循环的写法比普通for循环简便,不过我们还得考虑效率。 --->首先,我们先看结论: 对于基本数组类的遍历,两者的效率是相同的; 对于...
  • 增强for循环: 这种for循环的内部是调用了Iterator实现的(实现了Iterator接口),和Iterator遍历效果是一样(你可以断点调试跟踪代码看看内部原理),主要用于遍历数组、集合的每一个元素。 优点:1.写法简便 2.....
  • 在遍及集合过程中对集合进行删除操作最好不要做,如果非要做可以利用迭代器,并发集合,或者同步代码。  单线程模式下直接使用迭代器提供的remove方法就行或者首先记录下标遍历... 普通for循环遍历集合过程中进行...
  • 在JAVA中,遍历集合和数组...for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i) + ","); } Iterator iterator = list.iterator(); while (iterator.hasNext()) { System.out.print(ite...
  • 迭代器和增强for循环

    2020-12-31 10:57:20
    今天写一个小代码时,突然对增强for循环中能不能删除元素产生了疑问,借此整理一下,可能理解的不够深刻,之后有新的发现再更新。 今天写的代码如下: 在ArrayList中插入四个元素,然后通过增强for循环遍历删除倒数...
  • 这时候大家都不会使用增强for循环的方式来遍历List,因为它会抛java.util.ConcurrentModificationException异常。比如下面的代码就会抛这个异常: List list = new ArrayList(); list.ad...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,120
精华内容 21,248
关键字:

增强for循环删除