遍历集合的常用方法一(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自己就迷失了方向。