关于java集合的遍历以及ConcurrentModificationException(并发操作异常)

来源:互联网 发布:linux修复windows引导 编辑:程序博客网 时间:2024/06/08 06:04

遍历集合的常用方法一(Iterator(迭代器)遍历):
迭代器接口Iterator
Iterator it = collection.iterator(); //返回接口的子类对象,多态
迭代器的方法:
next(); 返回迭代器的下一个元素,其实就是获取迭代器的元素,并且移动到下一个元素的地址
hasNext(); 判断是否有元素可以被迭代,如果有则返回true

迭代器为什么是一个接口而不是一个具体的类???
如果迭代器是一个具体的类,则它的方法全是具体的方法,而由于集合的数据结构的不同,则各种集合的存储方法是不一样。所以用一个具体的实现类来实现所有的集合的遍历是不可以的,所以迭代器不能是一个具体的类。

Iterator it = c.iterator();      while( it.hasNext()){          Student s = (Student) it.next();          //尽量不要使用System.out.println(it.next());          //除非你重写了 toString();不然会打印地址        System. out.println(s .getName());    }

每次执行.next()后。都会指向下一个元素,所以不要在一个输出语句里面出现两次 .next();
ListIterator 与 Iterator
ListIterator是Iterator的子接口:
ListIterator li = collection.listIterator();
Iterator it = collection.iterator();
ListIterator有个特有功能可以逆向遍历

    ListIterator it = c .listIterator();      while( it.hasNext()){          Student s = (Student) it.next();          System. out.println(s .getName());    }      while( it.hasPrevious()){          Student s = (Student) it.previous();          System. out.println(s .getName());    }   //你必须在正向遍历之后才能逆向

并发修改的异常(ConcurrentModificationException):

ListIterator lit = list.listIterator();           while (lit.hasNext()) {                String s = (String) lit.next();                if (list.contains("lisi")) {                     lit.add("zhaoliu");    //会抛出一个并发修改异常               //ConcurrentModificationException                           }          }

为什么?
迭代器是依赖于集合而存在的。
我们在通过迭代器迭代的过程中,用集合往集合中添加了元素。
而并没有重新获取迭代器,所以,报错。
原因:
在迭代器迭代的过程中,是不能通过集合去修改集合的。
解决方案:(只要使用迭代器和用集合修改元素不同时做就好)
A:用集合本身遍历集合,用集合去修改集合。
集合实现。添加成功,元素添加到末尾。
B:用迭代器迭代,用迭代器修改元素。
迭代器实现。添加成功,遍历到哪里,添加到哪里。ListIterator()有个add方法
使用迭代器和用集合修改元素时不会出现异常的特殊情况:
这里写图片描述

遍历集合的常用方法二(增强for循环):
增强for循环:其实就是迭代器
for(Collection集合或者数组中的元素的数据类型 变量 : Collection集合或者数组名称) {
使用变量即可。该变量其实就是集合或者数组中的元素。
}

           int[]  arr = {0,1,2,3,4};          //普通for循环          for(int i =0;i <arr .length ;i ++){              System. out.println(arr [i ]);          }          //增强for循环          for(int i :arr ){              System. out.println(i );          }
   List<String> array = new ArrayList<String>();         array.add( "hello");         array.add( "world");         array.add( "java");         //此处的for循环的类型就是String         for (String str : array ) {            System. out.println(str );        }

该异常的原因:

Iterator是工作在一个独立的线程中,并且拥有一个 mutex锁,就是说Iterator在工作的时候,是不允许被迭代的对象被改变的。Iterator被创建的时候,建立了一个内存索引表(单链表),这 个索引表指向原来的对象,当原来的对象数量改变的时候,这个索引表的内容没有同步改变,所以当索引指针往下移动的时候,便找不到要迭代的对象,于是产生错 误。List、Set等是动态的,可变对象数量的数据结构,但是Iterator则是单向不可变,只能顺序读取,不能逆序操作的数据结构,当 Iterator指向的原始数据发生变化时,Iterator自己就迷失了方向。

1 0
原创粉丝点击