前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你有没有掉进去过这些 迭代器 的 “陷阱“

你有没有掉进去过这些 迭代器 的 “陷阱“

作者头像
RiemannHypothesis
发布2022-08-19 16:42:37
2040
发布2022-08-19 16:42:37
举报
文章被收录于专栏:Elixir

一、迭代数组或集合时的 ”陷阱“

对于集合和数组的迭代,最常用的方式就是使用 for 循环迭代器 进行迭代。新建一个 Maven 项目 iterator-traps, 添加 junit 依赖。

代码语言:javascript
复制
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

在 test 包下创建测试类 com.traps.IterationTest,用于测试 for 循环 迭代和 迭代器 迭代

for 循环迭代

当需要对一个数组进行遍历的时候,可以使用 for 循环通过数组长度,建立索引来实现迭代

代码语言:javascript
复制
public class IterationTest {

    @Test
    public void testForeachByUsingIndex(){
        int[] items = new int[]{1,2,3,4};

        for (int i = 0; i < items.length; i++) {
            System.out.println(items[i]);
        }
    }
}

执行上述代码,输出结果如下:

代码语言:javascript
复制
1
2
3
4

for 循环可以非常简单的通过索引来循环获取数组中的每一个元素。

迭代器迭代

迭代器 Iterator 是一种用于访问集合的方法,可以用于迭代集合,Iterator 接口是 Java 迭代器中最简单的实现,Java 中的集合 Collection 接口都有一个 iterator() 方法,该方法可以返回一个 Iterator 对象,Iterator 对象本身并不存放任何元素或者对象。

迭代器 模式提供了一种方法来顺序访问一个聚合对象中的各个元素,而不保留该对象的内部表示,迭代器模式是一种对象行为型模式,其主要优点如下:

  • 访问一个聚合对象的内容而无须暴露它的内部表示。
  • 将遍历任务交由迭代器完成,简化了聚合类。
  • 支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
  • 增加新的聚合类和迭代器类都很方便,无须修改原有代码。
  • 封装性良好,为遍历不同的聚合结构提供一个统一的接口。

在 IterationTest 测试类中增加测试方法 testIterateCollections

代码语言:javascript
复制
public class IterationTest {

    // 其余代码保持不变 
    
    private static Collection<String> zulu = Arrays.asList("Seal A", "Seal B", "Seal C", "Seal D");

    private static Collection<String> yankee = Arrays.asList("Seal Z", "Seal Y", "Seal X", "Seal W", "Seal V");

    @Test
    public void testIterateCollections(){
        for (Iterator<String> items = yankee.iterator(); items.hasNext();){
            System.out.println(items.next());
        }
    }

}

执行上述代码,输出记过如下:

代码语言:javascript
复制
Seal Z
Seal Y
Seal X
Seal W
Seal V

但是当嵌套迭代两个集合时,会出现异常

代码语言:javascript
复制
@Test
public void testNestIterateCollections(){
    for (Iterator<String> items = yankee.iterator(); items.hasNext();){
        for (Iterator<String> eles = zulu.iterator(); eles.hasNext();){
            System.out.println(items.next() + " " + eles.next());
        }
    }
}

执行上述代码,输出记过如下:

代码语言:javascript
复制
Seal Z Seal A
Seal Y Seal B
Seal X Seal C
Seal W Seal D
Seal V Seal A

java.util.NoSuchElementException
    at java.util.AbstractList$Itr.next(AbstractList.java:364)
        .....................

这是应为对于外部集合来说, next 调用次数太多,导致集合中的元素已经迭代完了还在调用 next,应该是在外部循环中调用 next 而不是在内嵌的循环中调用最外层迭代器的 next。

修改 testNestIterateCollections 方法

代码语言:javascript
复制
@Test
public void testNestIterateCollections(){

    for (Iterator<String> items = yankee.iterator(); items.hasNext();){
        String code= items.next();
        for (Iterator<String> eles = zulu.iterator(); eles.hasNext();){
            System.out.println(code + " " + eles.next());
        }
    }
}

执行上述代码,输出结果如下:

image.png
image.png
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、迭代数组或集合时的 ”陷阱“
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档