迭代器的简单应用实践

迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。

在遍历容器时,我们可以使用for循环或者是增强for循环,但是不同的集合结构在遍历时,我们要针对集合特点采取不同的方式,比如List是链表,我们可以直接当做数组处理,但Map是Key—Value的形式,我们只有获取了键名才能去遍历集合内容。

很麻烦对吧?
还好JDK为我们提供了一个接口-------Iterator(迭代器),迭代器为各种容器提供了公共的操作接口。这样使得对容器的遍历操作与其具体的底层实现相隔离,达到解耦的效果。

查看Iterator的API我们得知,该接口共有3个方法:
图片描述

查看API发现Collection实现了该接口,也就是说Collection的所有子实现类可使用Iterator的方法,同时在Collection中定义了一个方法iterator()

图片描述

使用该方法iterator(),要求容器返回一个Iterator对象。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
那我们如何使用迭代器呢?

示例代码如下,关键代码的解释说明已经在注释部分给出,将不再做赘述。

示例代码:

/**
 * + 上海尚学堂 shsxt.com
 */
public class TestIterator {
    
    public static void main(String[] args) {
        List<String> list= new ArrayList();
        list.add("and");
        list.add("try");
        list.add("your");
        list.add("best");
        
        //使用迭代器,对集合Arraylist中的元素进行取出
        //调用集合的方法iterator() 获取Iterator接口的实现类对象()
        Iterator<String> it=list.iterator();
        System.out.println(list.iterator().getClass());//打印的内容是 class java.util.ArrayList$Itr 既是我们的接口的实现类对象
         //接口实现类对象,调用方法hasNext()判断集合中是否有元素
        boolean b = it.hasNext();
        System.out.println(b);
        //接口的实现类对象,调用方法next()取出集合中的元素
        String s = it.next();
        System.out.println("it.next()"+s);
        while(it.hasNext()){
            /*
             * 这里将不会输出"and",因为我们调用一次hasNext,内部的指针就会指向下一个元素
             */
            System.out.println(it.next());
        }
        
    }
    
}

会遇到的问题(并发修改异常)
我们来设想如下的场景: 在list集合迭代元素中,对元素进行判断,一旦条件满足就添加一个新元素。代码如下

/**
 * + VX:java8733 获取更多资源
 */

    List<String> list2 = new ArrayList<String>();
        list2.add("abc");
        list2.add("def");
        list2.add("g");
        
        Iterator<String> it=list2.iterator();
        while(it.hasNext()){
            String str=it.next();
            if("g".equals(str)){
                //该操作会导致程序异常: ConcurrentModificationException
                List2.add("b");
            }
        }
        System.out.println(list2);

我们会发现当我们使用迭代器遍历元素的时候,通过集合是不能修改元素的。程序抛出异常ConcurrentModificationException,这个异常指的是当方法检测到对象的并发修改,但不允许这种修改时,就会抛出此异常。

这是为什么呢? why?

 迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。 

那我们应该如何解决呢?
首先,在迭代时,尽量不要使用集合的方法操作元素。如果要在迭代时对元素操作。我们可以通过ListIterator迭代器来操作元素。

我们可以将上面的代码做如下的修改就可以操作list中的元素了

 /**
 * 上海尚学堂 shsxt.com
 */

ListIterator<String> it=list2.listIterator();
        while(it.hasNext()){
            String str=it.next();
            if("a".equals(str)){
                //子接口ListIterator包含add()方法
                it.add("b");
            }
        }

上海尚学堂Java原创文章,感谢您阅读,后续Java技术文章陆续奉上,请多关注

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值