`
fulerbakesi
  • 浏览: 561910 次
文章分类
社区版块
存档分类
最新评论

Iterator迭代器,不可蜻蜓点水

阅读更多
<style></style>

对于java基础了解多少呢?对于Iterator迭代器,掌握多少嗯?是否真正会用了呢?

在做项目中,需求如下:后台传过来list对象,界面显示需要删除list的某一个对象。

解决办法如下:

第一种:其实后台直接传过来已经删除某个对象的list即可,在dao层的sql语句完成。界面直接循环list显示即可。

第二种:后台传过来完整的list对象,界面显示时,先删除list某一个对象,然后再循环显示删除后的list

本人使用的是第二种做法,因为项目是分工开发的,后台已经完成并已封装。其实仔细思考后,没哟必要在后台再添加一个方法,直接在业务逻辑层中或actionjsp中再次加工而已。

list中删除一个对象,肯定是先遍历,然后找出不符合的,直接在集合中删除即可。

其中,java容器,Collection,Set,List,Map等等,这块,我曾经做过总结,感兴趣的可以浏览一下。当时做的总结,是把接口的分类,但没有涉及到其中的方法,add,remove,get等等。

首先看一下java代码:

    public static void main(String[] args) {
    List c=new ArrayList();
        c.add("测试迭代器");
        c.add("测试java容器");
        Iterator it=c.iterator();
        while(it.hasNext()){
            String test=(String)it.next();
            if("测试java容器".equals(test)){
                 c.remove(test);
            }
        }
            System.out.println(c);
    }

这段java代码,看出猫腻了吗?乍一看,思路完全正确啊。那结果应该会输出[测试迭代器]呀。可以结果却不是如此。

执行这段java代码,抛出异常。

    Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
    at java.util.AbstractList$Itr.next(Unknown Source)
    at TestIterator.main(TestIterator.java:22) 

产生错误的原因在于没有正确理解Iterator迭代器。

其实,迭代器是采用了快速失败的原理,一旦发现自己遍历的集合被修改,就像 c.remove(test);程序把集合c进行修改,则报以上的错误。其实这种错误经常在多线程中出现,一个线程在遍历集合,突然另一个线程把集合中的数据进行篡改。这种现象肯定是不允许出现的,报以上错误就是为了防止多线程共享资源发生资源争夺问题。

那如何避免这个问题呢?如何删除呢?

使用迭代器Iterator中的remove方法,Iterator迭代器一共三个方法,hasNext(),判断是否有下一个集合元素;Next(),返回的集合中下一个元素;remove()删除迭代器刚刚next的集合元素。

真正理解了这三个方法,使用就灰常简单了。

直接把c.remove(test);改成it.remove();即可。运行结果肯定必须也如愿以偿的是[测试迭代器];

另外在上述代码中进行改动一下,运行结果又是如何的呢?

    public static void main(String[] args) {
        List c=new ArrayList();
        c.add("测试迭代器");
        c.add("测试java容器");
        Iterator it=c.iterator();
        while(it.hasNext()){
            String test=(String)it.next();
            if("测试java容器".equals(test)){
                             test="测试成功";
            }
           }
        System.out.println(c);
    }

运行结果是[测试迭代器,测试java容器]。咦,为何没有发生变化呢?又得要重新理解Iterator迭代器了。

因为迭代器Iterator循环遍历集合元素时,并不是把集合元素给了迭代器变量test,而是把集合元素的值赋给了迭代器变量test,所以修改迭代器变量test的值时,并不是影响到集合元素。

这种情况就如值传参和引用传参。值传参,不会影响到原来的变量。而引用传参,则会影响到原来的变量,因为引用传参是指向的同一个内存区域。

通过这次异常,发现基础的重要性。同时也意识到,基础虽重要,理解也灰常重要。有些东西需要囫囵吞枣,走马观花,蜻蜓点水,不求甚解。但是有些东西必须做到咬文嚼字,耳熟能详,一清二楚,烂若披掌,了如指掌。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics