对于java基础了解多少呢?对于Iterator迭代器,掌握多少嗯?是否真正会用了呢?
在做项目中,需求如下:后台传过来list对象,界面显示需要删除list的某一个对象。
解决办法如下:
第一种:其实后台直接传过来已经删除某个对象的list即可,在dao层的sql语句完成。界面直接循环list显示即可。
第二种:后台传过来完整的list对象,界面显示时,先删除list某一个对象,然后再循环显示删除后的list。
本人使用的是第二种做法,因为项目是分工开发的,后台已经完成并已封装。其实仔细思考后,没哟必要在后台再添加一个方法,直接在业务逻辑层中或action或jsp中再次加工而已。
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的值时,并不是影响到集合元素。
这种情况就如值传参和引用传参。值传参,不会影响到原来的变量。而引用传参,则会影响到原来的变量,因为引用传参是指向的同一个内存区域。
通过这次异常,发现基础的重要性。同时也意识到,基础虽重要,理解也灰常重要。有些东西需要囫囵吞枣,走马观花,蜻蜓点水,不求甚解。但是有些东西必须做到咬文嚼字,耳熟能详,一清二楚,烂若披掌,了如指掌。
- 15楼qq10281845昨天 08:20
- [code=java]npublic static void main(String[] args) {n List c=new ArrayList();n c.add("测试迭代器");n c.add("测试java容器");n Iterator it=c.iterator();n while(it.hasNext()){n String test=(String)it.next();n if("测试java容器".equals(test)){n test="测试成功";n }n }n System.out.println(c);n }n[/code]n表示对这个例子很不理解,在迭代的时候好像根本都没有对c操作,打印的结果肯定[测试迭代器,测试java容器],为什么会这样问呢?
- Re: qq10281845昨天 09:52
- 求楼主解释!!
- Re: llhhyy1989昨天 14:36
- 回复qq10281845nString test=(String)it.next(); n test="测试成功"; n这个迭代器循环赋值给迭代器变量了。
- Re: qq10281845昨天 21:14
- 回复llhhyy1989n但是前面一直都没有对List c这个集合操作吧?它的值应该就是原本的值,而且迭代的Iterator it这个集合,两者直接没有直接对数据的操作,只是把c的值赋给it,在操作it的时候,没有对c做任何操作,打印[测试迭代器,测试java容器]这个结果,应该没问题,想不明白。继续求解释。。
- Re: llhhyy1989昨天 22:55
- 回复qq10281845n(*^__^*) 嘻嘻……,你理解着对着呢。因为String test=(String)it.next(); 有的人曾说是吧集合元素给了test,这样,test改变,其对应的集合元素也发生变化,也就是部分人认为“测试java容器”被改成“测试成功”。其实不是,只是把集合元素的值给了test,所以test改变,不会影响其对应的集合元素。
- Re: llhhyy198911小时前
- 回复llhhyy1989n有些人疑为输出:[测试迭代器,测试成功]。并且为了说明“ 因为迭代器Iterator循环遍历集合元素时,并不是把集合元素给了迭代器变量test,而是把集合元素的值赋给了迭代器变量test,所以修改迭代器变量test的值时,并不是影响到集合元素。”
- 14楼haizhijiaotianzhiya昨天 23:30
- 顶一个。。。
- 13楼xjc1278003262前天 17:11
- 给师姐顶了,先学习着,等待日后用
- Re: llhhyy1989昨天 22:53
- 回复xjc1278003262n[e10] 呵呵,谢谢关注!
- 12楼liuyanlinglanq前天 17:09
- 支持
- 11楼liusong0605前天 17:08
- 很详细,谢谢分享!
- 10楼happyITer前天 16:54
- 发现问题,就是进步的开始,加油!!!
- Re: llhhyy1989前天 16:55
- 回复happyITern说的很好!重要的是发现问题。(*^__^*) 嘻嘻……
- 9楼xqf309前天 16:53
- 有些不能蜻蜓点水[e01]
- 8楼lishehe前天 16:52
- 顶
- 7楼haigegegege前天 16:52
- 好事要多磨。
- 6楼zlh6688前天 16:50
- 确实基础很重要,打基础需要一个过程。
- Re: llhhyy1989前天 16:51
- 回复zlh6688n基础是一个人高发展,深发展的本钱。
- 5楼zhanglianhai555前天 16:40
- 虽然看不懂,但我支持你!!!!!
- Re: llhhyy1989前天 16:49
- 回复zhanglianhai555n[e10] O(∩_∩)O谢谢您支持
- 4楼lfmilaoshi前天 16:39
- 有些东西需要囫囵吞枣,走马观花,蜻蜓点水,不求甚解。但是有些东西必须做到咬文嚼字,耳熟能详,一清二楚,烂若披掌,了如指掌。n宏观和微观。。。。米老师
- 3楼qq10281845前天 15:40
- 大概看明白楼主说的问题,后面输出c的值,感觉不怎么合适,如果是输出it的值这样应该可以更好的表达楼主的意思,楼主你觉得呢
- Re: llhhyy1989前天 15:58
- 回复qq10281845n不是啊,因为部分人认为集合c发生变化了,应该输出c呀。其实c没有发生变化啊。呵呵,谢谢一直关注,互相交流哈。
- 2楼rankun203前天 15:35
- 哟西哟西,非常感谢迭代器一文,现在在学Jsp初步,有很多其他知识在学,但还是要经常来看看你们提高班的文章...嘿嘿.
- Re: llhhyy1989前天 15:39
- 回复rankun203n谢谢支持哈![e10]
- 1楼smszhuang168前天 15:30
- 第二个例子要表达什么意思没太明白
- Re: llhhyy1989前天 15:33
- 回复smszhuang168n因为迭代器Iterator循环遍历集合元素时,并不是把集合元素给了迭代器变量test,而是把集合元素的值赋给了迭代器变量test,所以修改迭代器变量test的值时,并不是影响到集合元素。