1.综合了解概念
为了方便的处理集合中的元素,Java中出现了一个对象,该对象提供了一些方法专门处理集合中的元素.例如删除和获取集合中的元素.该对象就叫做迭代器(Iterator).
对 Collection 进行迭代的类,称其为迭代器。还是面向对象的思想,专业对象做专业的事情,迭代器就是专门取出集合元素的对象。但是该对象比较特殊,不能直接创建对象(通过new),该对象是以内部类的形式存在于每个集合类的内部。
如何获取迭代器?Collection接口中定义了获取集合类迭代器的方法(iterator():返回该集合的迭代器对象),所以所有的Collection体系集合都可以获取自身的迭代器。
-
Iterator即Collection接口的迭代器
-
Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
-
所有实现了Collection接口的容器类都有一个iterator方法
该类主要用于遍历集合对象,该类描述了遍历集合的常见方法
Iterator接口定义的方法
Iterator 该接口是集合的迭代器接口,定义了常见的迭代方法 1.boolean hasNext() 判断集合中是否有元素,如果有元素则可以迭代就返回true 2.E next() 返回迭代的下一个元素 注意:如果没有下一个元素时,调用next元素会抛出NoSuchElementException异常 next方法的返回类型时Object 为什么next方法的返回类型是Object的呢? 答:为了可以接收任意类型的对象,那么返回的时候,不知道是什么类型的就定义为object
2.迭代器的遍历
第一种方式:while循环
public static void main(String[] args) {
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
Iterator it = list.iterator();
while (it.hasNext()) {
String next = (String) it.next();//next()的返回值类型为Object类型,需要转换为相应类型,不转换也是可以的
System.out.println(next);
}
不转换例子如下:
while (it.hasNext()) {
System.out.println(it.next());
}
可以看出迭代器对象就像是一个集合类对象的游标指针,通过hasNext()判断是否还有下一个元素,通过next()移动游标指向下一个元素。
第二种方式:for循环
public class Demo2 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
for (Iterator it = list.iterator(); it.hasNext();) {
//迭代器的next方法返回值类型是Object,所以要记得类型转换。
String next = (String) it.next();
System.out.println(next);
}
}
需要取出所有元素时,可以通过循环,java 建议使用for 循环。因为可以对内存进行一下优化。
第三种方式:使用迭代器清空集合
public class Demo1 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");
System.out.println(coll);
Iterator it = coll.iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
System.out.println(coll);
}
细节一:
如果迭代器的指针已经指向了集合的末尾,那么如果再调用next()会返回NoSuchElementException异常
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
Iterator it = list.iterator();
while (it.hasNext()) {
String next = (String) it.next();
System.out.println(next);
}
// 迭代器的指针已经指向了集合的末尾
// String next = (String) it.next();
// java.util.NoSuchElementException
细节二:
如果调用remove之前没有调用next是不合法的,会抛出IllegalStateException
List<String> arr=new ArrayList<>();
arr.add("a");
arr.add("b");
arr.add("c");
out.println(arr);//输出:[a, b, c]
Iterator<String> it=arr.iterator();//collection接口中定义了获取集合迭代器的方法.iterator()
//使用迭代器清空集合元素
for(it=arr.iterator();it.hasNext();){
it.next();// 调用remove之前没有调用next是不合法的,//会抛出java.lang.IllegalStateException
it.remove();
}
out.println(arr);//输出:[],因为清空了
3.迭代器原理
注意:1.在对集合进行迭代过程中,不允许出现迭代器以外的对元素的操作,因为这样会产生安全隐患,java会抛出异常并发修改异常(ConcurrentModificationException),普通迭代器只支持在迭代过程中的删除动作。
2.ConcurrentModificationException: 当一个集合在循环中即使用引用变量操作集合又使用迭代器操作集合对象, 会抛出该异常。
public class Demo1 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");
System.out.println(coll);
Iterator it = coll.iterator();
while (it.hasNext()) {
it.next();
it.remove();
coll.add("abc"); // 出现了迭代器以外的对元素的操作
}
System.out.println(coll);
}
如果是List集合,想要在迭代中操作元素可以使用List集合的特有迭代器ListIterator,该迭代器支持在迭代过程中,添加元素和修改元素。
3.List特有的迭代器ListIterator
public interface ListIterator extends Iterator
ListIterator<E> listIterator()
---| Iterator
hasNext()
next()
remove()
------| ListIterator: Iterator子接口 List专属的迭代器
add(E e) 将指定的元素插入列表(可选操作)。该元素直接插入到 next 返回的下一个元素的前面(如果有)
void set(E o) 用指定元素替换 next 或 previous 返回的最后一个元素
hasPrevious() 逆向遍历列表,列表迭代器有多个元素,则返回 true。
previous() 返回列表中的前一个元素。
Iterator在迭代时,只能对元素进行获取(next())和删除(remove())的操作。
对于 Iterator 的子接口ListIterator 在迭代list 集合时,还可以对元素进行添加
(add(obj)),修改set(obj)的操作。
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
// 获取List专属的迭代器
ListIterator lit = list.listIterator();
while (lit.hasNext()) {
String next = (String) lit.next();
System.out.println(next);
}
逆序遍历集合:hasPrevious() 和 previous()
public class Demo2 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
// 获取List专属的迭代器
ListIterator lit = list.listIterator();
while (lit.hasNext()) {
String next = (String) lit.next();
System.out.println(next);
}
System.out.println("***************");
while (lit.hasPrevious()) {//逆序遍历列表
String next = (String) lit.previous();//返回列表中的前一个元素
System.out.println(next);
}
}
ListIterator 的set() 方法 : 用指定元素替换 next 或 previous 返回的最后一个元素
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);//[计算机网络, 现代操作系统, java编程思想, java核心技术, java语言程序设计]
// 获取List专属的迭代器
ListIterator lit = list.listIterator();
lit.next();//计算机网络
lit.next();//现代操作系统
lit.set("古代操作系统");//将现代操作系统替换为古代操作系统
while(lit.hasNext()){
out.print(lit.next()+" ");//输出:java编程思想 java核心技术 java语言程序设计
}
out.println();
out.println(list);//[计算机网络, 古代操作系统, java编程思想, java核心技术, java语言程序设计]
add方法将指定的元素插入列表,该元素直接插入到 next 返回的元素的后面
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
ListIterator lit = list.listIterator();
lit.next(); // 计算机网络
lit.next(); // 现代操作系统
System.out.println(lit.next()); // java编程思想
// 将指定的元素插入列表,该元素直接插入到 next 返回的元素的后
lit.add("平凡的世界");// 在java编程思想后添加平凡的世界
System.out.println(list);//[计算机网络, 现代操作系统, java编程思想, 平凡的世界, java核心技术, java语言程序设计]