Iterator

iterator对象成为迭代器——设计模式的一种,主要用于遍历Collection集合中的元素。

迭代器被定义为提供一种访问一个容器(container)对象中各个元素,而不需要暴露该对象的内部细节。迭代器模式,就是为容器而生。

使用iterator遍历集合

//省略往集合中放入元素
...

Iterator iterator = coll.iterator();
//不推荐使用
for(int i = 0;i<list.size;i++){
System.out.println(inerator.next());
}
//推荐使用
while(iterator.hasNext()){
System.out.println(iterator.next());
}

实际上当迭代器被创建的时候,迭代器的指针指向null,当调用haxNext()时候,判断是否有下一个元素,如果有就调用next(),next()方法会使指针下移,并且将下移以后集合位置上的元素返回。

需要明确的是hasNext()仅仅起到了判断的作用,真正操作指针的是next();Iterator的使用和原理,增强for循环的原理_增强for循环


  • 迭代器并不是容器,它就好像是乘务员,只是起到检票的作用。
  • 集合对象每次调用迭代器对象的时候每次都会创建一个新的迭代器对象。

//错误写法
for(coll.iterator().hasNext()){
//死循环,并且每次输出的都是集合中的第一个元素。
System.out.println(coll.iteeator.next());
}

迭代器的Remove()方法

此方法不同于集合直接调用remove()

Iterator iterator = coll.Iterator();
for(iterator.hasNext()){
Object obj = iterator.next();
if("Tom".equals(obj)){
iterator.remove();
}
}

  1. 如果想要查看集合中有什么元素需要再重新生成迭代器,因为上一个迭代器的指针已经指向了集合的末尾。
  2. 如果没有掉用next()之前不要调用remove()方法,因为此时指针指向null,连续调用两次remove()也是会发生同样的异常。
  3. 迭代器只是用来调用Collection的,不能用来调用Map。

foreach()

jdk5.0提供了一种新的循环方式,称之为foreach或者增强for循环,用来遍历集合或者数组。

//for(集合元素的类型 局部变量 : 集合对象)
for(Object obj : coll){
System.out.println(obj);
}

原理就是讲coll集合对象中的一项赋值给obj,然后输出,有就输出,没有就停止。增强for循环内部调用的还是迭代器。本质上一模一样,只是形式上变了而已。

这是一道面试题

//方式一
String[] arr = new String[]{"MM","MM","MM"};
for(int i = 0;i<arr.length;i++){
arr[i] = "GG";
}
//方式二
for(String str : arr){
str = "GG";
}
for(int i = 0;i<arr.length;i++){
System.out.println(arr);
}

  • 现象:方式一输出的数组元素全部被改变,方式二输出的数组元素没有被改变
  • 原因:增强for循环的str只是局部变量,是arr数组拿出值再赋值给str的,所以更改str不会对数组元素进行修改。