一.介绍
迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。
迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来。
二.内容
集合用来持有数据,一定会设计出对数据的增、删、改、查四个常用方法,而查是集合中最常用的功能。Collection接口继承了Iterable接口,具备了可迭代功能iterator方法,该方法用于迭代集合。所以,所有单列集合由于是Collection的直接或间接实现类,均具有该方法。
这里涉及到以下内容共同完成集合的迭代:
Collection接口的iterator方法,所以单列集合实现类均有该方法
iterator方法的返回值类型Iterator接口类型
Iterator接口的两个方法:hasNext与next方法
1.迭代常规步骤
(1)通过集合获取这个集合的迭代器
(2)结合使用迭代器的hashNext与next完成集合迭代
如:
ArryList<String> list = new ArryList <String>();
hs.add("i love java");
hs.add("i like java");
//返回迭代器
Iterator<String> iterator = list.iterator();
//调用hasNext与next完成集合迭代
while (iterator.hasNext()) {
String string = iterator.next();
System.out.println(string);
}
2.Collection接口的Iterator
方法声明为:
Iterator<集合中数据类型> iterator()
用来返回专属于该集合对象的迭代器对象(Iterator的子类对象)。
3.Iterator接口
该接口规定了迭代集合所需要的方法
4.Iterator接口的两个方法:hasNext与next方法
Iterator规定了两个方法,集合对象产生的迭代器对象正是通过这两个方法帮助集合进行迭代工作的。
调用迭代器的hasNext方法判断是否有下一个元素
调用迭代器的next获取下一个元素
5.迭代集合元素图解:
6.代码演示
importjava.util.ArrayList;
importjava.util.Collection;
importjava.util.Iterator;
/*
* Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器。
*
* Iterator 就是帮你去做遍历集合操作 .
*
* iterator() 返回的就是 Iterator接口的子类对象.
*/
public class Demo2 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("111");
c.add("222");
c.add("333");
c.add("444");
// 遍历集合. 获取其中每一个元素.
// 1.获取迭代器对象 .
Iterator iterator = c.iterator(); // Iterator 接口 指向 子类对象.
// 2.调用迭代器的方法,获取集合中的元素.
// Object next = iterator.next();
// System.out.println(next);
//
// Object next2 = iterator.next();
// System.out.println(next2);
//
// Object next3 = iterator.next();
// System.out.println(next3);
//
// Object next4 = iterator.next();
// System.out.println(next4);
//
// Object next5 = iterator.next(); //NoSuchElementException
// System.out.println(next5);
while(iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
}
7.迭代器遍历集合总结
importjava.util.Collection;
importjava.util.Iterator;
importjava.util.ArrayList;
/*
* 1.hasNext 方法和 next方法 说明 . 遍历之前,有一个指针指向初始位置,第一个元素的前面,
* hasNext,判断是否在指针后面有元素,有返回true ,没有返回false .
* 如果有 , 就可以通过 next() 获取下一个元素了.
* 2.syso(c); 我也能看所有的元素, 那我为什么还要遍历呢?
*
* 3.toString() 在哪重写的呢? 你管的着么!! 要找找他爹,他爷爷
*
*/
public class Demo3 {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("aaa");
c.add("abbbbb");
c.add("cccc");
c.add("xxxx ");
// 遍历集合
// 1.获取迭代器
Iterator iterator = c.iterator();
// 2.通过迭代器获取元素 .
while (iterator.hasNext()) { // 是否有下一个.
Object next = iterator.next(); // 获取下一个元素
System.out.println(next);
}
}
}
8.保存自定义对象练习(迭代器移除元素)
public class Student {
String name; // 姓名
int score; // 分数
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int score) {
super();
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
publicintgetScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "学生 [姓名=" + name + ", 分数=" + score + "]";
}
}
importjava.util.ArrayList;
importjava.util.Collection;
importjava.util.Iterator;
/*
* 给你集合 ,保存 很多 学生对象. 学生类中, 包含了姓名和分数.
*
* 学生1 ("老王" , 66) ;
* 学生2 ("金莲" , 28) ;
* 学生3 ("西门" , 99) ;
*
* 1.把所有对象保存集合.
* 2.遍历集合,把60分以下的同学,移除掉.
* 3.再遍历的时候,只有 60分以上的同学了.
*/
public class Test {
public static void main(String[] args) {
//1. 创建学生对象
Student student1 = new Student("老王" , 66);
Student student2 = new Student("金莲" , 28);
Student student3 = new Student("西门" , 99);
Student student4 = new Student("大郎" , 100);
// 2.创建集合
Collection<Student> c = new ArrayList<>();
// 3.添加元素
c.add(student1);
c.add(student2);
c.add(student3);
c.add(student4);
System.out.println(c);
// 遍历集合,判断分数 .
//a.获取迭代器
Iterator<Student> it = c.iterator();
//b. 使用迭代器遍历
while (it.hasNext()) {
Student stu = it.next();
System.out.println(stu);
//获取分数
int score = stu.getScore();
//判断分数
if(score <60){
// 移除学生
//c.remove(stu);
it.remove(); // 移除当前迭代的元素. (迭代器移除方法可以避免并发修改异常)
}
}
// 再遍历集合
Iterator<Student> iterator = c.iterator();
while (iterator.hasNext()) {
Student student = iterator.next();
System.out.println(student.getName() +" --- "+ student.getScore());
}
}
}
9.三种遍历集合方式对比:
importjava.util.ArrayList;
importjava.util.Collection;
importjava.util.Iterator;
/*
* 1.集合变成数组 .遍历数组
* 2.迭代器 -- 必须掌握
* 3.增强for -- 必须掌握
*/
public class Demo2 {
public static void main(String[] args) {
Collection<Object> c = new ArrayList<>();
c.add(111);
c.add(222);
c.add(333);
//1.变成数组
Object[] array = c.toArray();
for (inti = 0; i<array.length; i++) {
System.out.println(array[i]);
}
System.out.println("============");
//2.迭代器
Iterator<Object> iterator = c.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
System.out.println("============");
//3.增强for
for (Object object : array) {
System.out.println(object);
}
}
}
10.并发修改异常(扩展)
迭代的常规用法中我们要尽量避免在迭代过程中为集合添加/删除数据。否则会报错,原因是Java抛出了并发修改异常。
迭代过程中并发修改异常的原因为迭代器中”记忆”的集合长度与集合中实际长度不同,而导致出现索引与实际元素不符甚至无限循环的情况发生。
所以在使用Iterator时,避免类似操作,for循环底层为迭代器实现,所以也需要避免类似操作。
有些迭代器避免了这样的问题,如ListIterator,但该类并不通用也不常用,实际开发中很少使用,只需要简单了解。
java中提供了很多个集合,它们在存储元素时,采用的存储方式不同。我们要取出这些集合中的元素,可通过一种通用的获取方式来完成。
importjava.util.ArrayList;
importjava.util.Collection;
importjava.util.Iterator;
importjava.util.List;
importjava.util.ListIterator;
/*
* 并发修改异常:当你 遍历集合并操作集合,添加或者移除元素的使用,可能会报出并发修改异常.
* 处理方式:添加,移除 ,使用迭代器的方法. 迭代器中的remove.
* 查看异常信息: 第一行是 异常的说明 _空指针 ,角标越界, 并发.....
* 详细异常信息, 从下往上看, 能看懂哪行就是你发生异常的地方,基本上就是你写错代码.
* Iterator.next()继续迭代的时候报错, 那么我们提供一种解决方案, 可以修改,但是不再遍历集合.
*
* 解决方案:
* 1.采用 Iterator中的方法 去操作集合 -- 推荐 !
* 2.使用非Iterator中的方法操作, 那么再操作之后 ,加 break;
*
*/
public class Demo {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("aaa");
c.add("bbb");
c.add("ccc");
c.add("ddd");
System.out.println(c);
Iterator<String> iterator = c.iterator();
while (iterator.hasNext()) {
String string= iterator.next();
// 如果存在bbb ,那么添加一个EEE
if (string.equals("bbb")) {
c.add("bbb");
break;
}
}
System.out.println(c); //java.util.ConcurrentModificationException 并发修改异常
List l = new ArrayList<>();
ListIteratorlistIterator = l.listIterator();
}
}