报错示例一:对象
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); for(String str : list){ if(!str.equals("1")) { list.remove(str); } } System.out.println(list.size());
错误使用二:这种状况不会报错,由于最后一个元素未被遍历到就程序跳出了循环遍历索引
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); for(String str : list){ if(!str.equals("1")) { list.remove(str); } } System.out.println(list.size());
方法一:for循环遍历rem
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); for (int i = 0; i < list.size(); i++) { String item = list.get(i); if("2".equals(item)) { //逻辑判断,剔除知足条件的元素 list.remove(item); //元素删除后,后面的元素位置向前挪一位,位置索引i须要自减一,不然访问不到后面的元素 i--; } } System.out.println(list.size());
方法二:使用集合的迭代器get
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); for(Iterator<String> it = list.iterator(); it.hasNext(); ){ if("2".equals(it.next())) { //使用迭代器的删除方法,不要使用集合对象的删除方法remove it.remove(); } } System.out.println(list.size());
缘由说明:it
一、若是使用加强for循环进行遍历,那么实际上使用的是集合的迭代器进行遍历,这时若是使用的是集合对象本身的删除方法,迭代器不知道元素集合发生了变化,进行获取下一个元素的时候就会爆出错误:ConcurrentModificationException,但这里有一点须要注意,若是遍历过程当中第一个被删除的元素处在倒数第二个被遍历的位置时,程序不会报错,正常结束。实际的结果是:集合中最后一个元素以前,会调用迭代器的hasNext()方法,该方法发现当前位置索引等于集合元素数量,判断遍历结束,跳出循环,实则最后一个元素未被遍历到。io
二、第一种遍历删除方法,是本身控制并调整元素位置索引,只要位置索引控制正确,就能够正常删除元素,不然会出现IndexOutOfBoundsExceptionfor循环
三、第二种遍历删除直接使用迭代器进行遍历,并且删除时使用的迭代器的删除元素方法,这个删除方法里面会对位置索引进行调整,使得迭代器在继续遍历查找下一个元素时,不会抛出异常错误。List