Iterator接口: 又叫做迭代器接口,仅用于遍历集合
容器在Java当中不是集合就是数组
相关方法:
iterator()
该方法与集合元素的遍历有关,返回Iterator接口的实例,用于遍历集合元素
next()方法,用来取数据
hasNext()方法
过程分析:
当返回Iterator对象时可以形象的理解为当前就有一个指针了,指针当前是指在第一个对象的前面那个位置,指的不是第一个对象,指的实际上是一个空的位置,调用hasNext是判断这个位置的后面是否有元素,此时就是看第一个位置是否有元素,发现有元素,返回的就是true,如果调用next方法,会让指针下移,并把下移之后到达的那个位置上的元素进行返回,当指针指向最后一个元素时,调用hasNext后面没有元素了,如果再调用next方法会出现异常
注意: hasNext只是进行一个判断,并不会让指针下移
Iterator只是用于遍历的,它不是容器,就只是一个迭代器,用来遍历的,调用iterator方法并没有新生成一个集合,遍历的数据都是原来容器中的数据
例子: 这里假设Person是定义的一个类,参数为name和age
且Person中重写了toString方法
Collection c=new ArrayList();
c.add(123);
c.add(456);
c.add(new Person("Jerry",20));
c.add(new String("Tom"));
c.add(false);
Iterator iterator=c.iterator();
//方式一不推荐
// System.out.println(iterator.next());//123
// System.out.println(iterator.next());//456
// System.out.println(iterator.next());//Person{name="Jerry",age=20}
// System.out.println(iterator.next());//Tom
// System.out.println(iterator.next());//false
//如果再多加一行System.out.println(iterator.next());会报异常,因为本来就只有5个元素
//方式二:通常也不这么写
//for(int i=0;i<c.size();i++) {
//System.out.println(iterator.next());
//}
//方式三
while(iterator.hasNext()) {//判断还有没有元素
System.out.println(iterator.next());
}
Iterator遍历集合的两种错误写法
错误写法一:
Collection c=new ArrayList();
c.add(123);
c.add(456);
c.add(new Person("Jerry",20));
c.add(new String("Tom"));
c.add(false);
Iterator iterator=c.iterator();
while(iterator.next()!=null) {
System.out.println(iterator.next());
}
分析: 第一次调用next拿到123,确实不等于null,但并没有输出123,直接进入while循环,输出456,同理,第二次进入while循环输出Tom,第三次在while循环头的时候,false不是null,进入循环,最后的结果就报异常了。
错误方式二:不先给iterator定义变量名,而是采用匿名的方式
Collection c=new ArrayList();
c.add(123);
c.add(456);
c.add(new Person("Jerry",20));
c.add(new String("Tom"));
c.add(false);
while(c.iterator().hasNext()) {
System.out.println(c.iterator().next());
}
这种是死循环,不断地输出123
每当我们调用iterator方法,都会返回迭代器对象,新的迭代器对象的指针是指向第一个元素之前的那个位置,所以每次进行hasNext判断都是true,因为每次判断都是拿着新的迭代器进行判断,输出的时候又拿了新的对象去进行输出123
注意:集合对象每次调用iterator方法都得到一个新的迭代器对象,默认游标都在集合的第一个元素之前
调用remove方法来移除集合中的元素
可以在遍历的过程中删除集合中我们不需要的元素
迭代器内部定义了remove方法,可以在遍历的时候删除集合中的元素,此方法不同于集合直接调用remove(),我们现在调用的是迭代器中的remove()方法
Collection c=new ArrayList();
c.add(123);
c.add(456);
c.add(new Person("Jerry",20));
c.add(new String("Tom"));
c.add(false);
Iterator iterator=c.iterator();
while(iterator.hasNext()) {
Object obj=iterator.next();//因为存的时候是按Object存的,所以取的时候也用Object
if("Tom".equals(obj)) {//最好不要写成obj.equals("Tom");因为如果obj中存的是null,这么做就空指针了
iterator.remove();//如果有的话,就移除"Tom"
}
}
//如果想从头遍历集合中的元素,不能这么干,因为出了上面的while循环,指针已经指向最后一个元素了
//while(iterator.hasNext()) {
//}
//应该重新得到一个iterator
iterator=c.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());//结果中就没有"Tom"了
}
注意:
如果还未调用next,或在上一次调用next之后已经调用了remove方法,再调用remove都会报异常
第一种情况:在没有调用next之前不要去调用remove,此时指针还没有移下来,删掉谁啊?
while(iterator.hasNext()) {
iterator.remove();
System.out.println(iterator.next());
}
第二种情况调用一次remove已经把元素干掉了,在调用next之前又调用一次remove,也不对,不能删两次
while(iterator.hasNext()) {
Object obj=iterator.next();//因为存的时候是按Object存的,所以取的时候也用Object
if("Tom".equals(obj)) {//最好不要写成obj.equals("Tom");因为如果obj中存的是null,这么做就空指针了
iterator.remove();//如果有的话,就移除"Tom"
iterator.remove();
}
}
Iterator只是用来遍历Collection的,Map的遍历不用迭代器