【Java】迭代器遍历

一、总述

所谓迭代,也就是遍历的意思:将元素一个一个获取出来。它是不依赖索引的,而是通过指针和移动的方式去获取元素。

我们来看一个场景:假设现在有一个长度为10的集合,我就可以获取一个迭代器对象,从头开始,一个一个的获取集合里面的元素,只不过迭代器有一个最大的特点,迭代器是不依赖索引的。

image-20240425193705968

迭代器在Java中的类是 Iterator,迭代器是集合专用的遍历方式。

在代码中,我们可以通过 iterator() 获取迭代器的对象,方法就会返回 Iterator 的对象。

Iterator<E> iterator():返回迭代器对象,默认指向当前集合的0索引。

然后再利用迭代器里面的两个方法

  • boolean hasNext():判断当前位置是否有元素,有元素返回 true,没有元素返回 false
  • E next():获取当前位置的元素,并将迭代器对象移向下一个索引位置

image-20240425194319904

接下来我们一起来看一个小案例。


二、案例

在这里有一个集合,里面存储了十个元素,迭代器的三个方法我也写好了。

先来看第一行:利用集合调用方法,获取到迭代器的对象,默认指向集合的 0索引

迭代器对象我们就可以看做下图的 光标 / 指针 / 箭头。

image-20240425194614245

然后再利用迭代器的对象调用 hasNext() 判断当前位置是否有元素,如果有元素,方法就会返回 true,如果没有,方法返回 false

可以发现,此时所在 0索引 是有元素的,因此此时这个方法返回 true

当这个迭代器的指针指向了最后一个元素的,后面一个位置时,此时就没有元素了,它会返回 false

image-20240425194910498

最后再利用迭代器调用 next() 获取元素并移动迭代器。

这个方法做了两件事情:1、获取元素;2、移动指针

例如下图,获取的就是 0索引"三",并将指针移动到了下一个索引处。

2gpbt-ds1o3

但是如果我需要获取集合中所有的元素该怎么办呢?

参数我们就可以通过循环来搞定:将 hasNext() 写在循环的判断条件中,如果当前位置有元素,方法返回 true,然后我们就进入到循环体中获取元素移动指针。

但是如果当前位置没有元素,方法返回 false,循环直接结束。

image-20240425195511628

三、代码实现

首先往集合中添加元素

Collection<String> coll = new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");

然后获取迭代器对象

迭代器就好比是一个箭头,默认指向集合的0索引处

Iterator<String> it = coll.iterator();

然后利用循环不断的去获取集合中的每一个元素

while(it.hasNext()){
    // next方法的两件事情:获取元素并移动指针
    String str = it.next();
    System.out.println(str);
}

四、细节

1、迭代器已经指向了最后一个元素的后一个位置,此时你还再次调用 next() 去获取元素的话,那么它会报 NoSuchElementException(没有这个元素异常)

image-20240425200711710 image-20240425201501516

但是它为什么报的是 NoSuchElementException 而不是索引越界异常呢?

因为迭代器在遍历的时候,是不依赖索引的,因此它没有报索引越界异常,而是 NoSuchElementException


2、迭代器遍历完成,指针是不会复位的

如果你还想将这个集合再次遍历一遍,需要重新再去获取一个迭代器的对象

第二次获取的时候,拿到的就是一个新的迭代器对象。

Iterator<String> it2 = coll.iterator();
while(it2.hasNext()){
    String str = it2.next();
    System.out.println(str);
}

3、循环中只能用一次 next(),如果你想多次使用到当前遍历的元素,就只能先用一个变量去记录,在下面直接使用变量就行了。

hasNext()next() 这两个方法需要配套使用,并且在使用的时候是一一对应的。

String str = it.next();
System.out.println(str);

4、迭代器遍历的时候,不能用集合的方法进行增加或者删除。

Iterator<String> it = coll.iterator();
while(it.hasNext()){
    String str = it.next();
    if("bbb".equals(str)){
        coll.remove("bbb"); // 这个就是用集合的方法进行删除
    }
}
System.out.println(coll);

此时就会报 ConcurrentModificationException(并发修改异常),它出现的原因就是:在迭代器遍历的时候,如果用集合的方法添加 / 删除,都会报这个错。

image-20240425203009077

那如何解决这种错误呢?打开一下帮助文档,我们需要来查看 Iterator 中还有哪些方法

可以发现在迭代器中,它提供了三个方法,其中第三个 remove() 就可以删除当前获取到的元素。

image-20240425203351166

因此如果需要在遍历的时候进行删除,就不能使用集合中的方法进行删除,而是需要使用迭代器中的方法进行删除。

程序运行完毕,可以发现 "bbb" 已经成功被删掉了。

Iterator<String> it = coll.iterator();
//3.利用循环不断的去获取集合中的每一个元素
while(it.hasNext()){
    //4.next方法的两件事情:获取元素,并移动指针
    String str = it.next();
    if("bbb".equals(str)){
        it.remove();
    }
}
System.out.println(coll); // [aaa, ccc, ddd, eee]

在遍历的过程,不可以使用集合的方法进行增加 / 删除,但是当集合遍历完成后,就可以使用集合的方法进行增加 / 删除。


五、总结

1、迭代器在遍历集合的时候是不依赖索引的

它是通过创建指针,并且移动指针的方式去获取到集合中的每一个元素。

2、迭代器需要掌握的三个方法

Iterator<String> it = coll.iterator();
while(it.hasNext()){
    String str = it.next();
    System.out.println(str);
}

3、迭代器的四个细节

① 迭代器已经指向了最后一个元素的后一个位置,此时你还再次调用 next() 去获取元素的话,那么它会报 NoSuchElementException(没有这个元素异常)

② 迭代器遍历完成,指针是不会复位的

如果你还想将这个集合再次遍历一遍,需要重新再去获取一个迭代器的对象

第二次获取的时候,拿到的就是一个新的迭代器对象。

③ 循环中只能用一次 next(),如果你想多次使用到当前遍历的元素,就只能先用一个变量去记录,在下面直接使用变量就行了。

④ 迭代器遍历的时候,不能用集合的方法进行增加或者删除。

  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值