A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 依然超级赛亚人 高级黑马   /  2014-8-7 16:06  /  3656 人查看  /  32 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 依然超级赛亚人 于 2014-8-13 08:06 编辑

今天在做迭代器相关的练习时,我在用while遍历元素之后又在下面加了一个同样的while语句,结果没有看到我预想中的打印两次结果,而且编译和运行都没报错,就是没打印出两次结果,好像只执行了一个while。想了半天不知怎么回事,想在论坛中请教一下大家,如下面代码:


import java.util.*;
class IteratorTest02
{
        public static void main(String[] args)
        {
                Person p1 = new Person("张三",28);
                Person p2 = new Person("李四",35);
                Person p3 = new Person("王五",38);
                Person p4 = new Person("张三",28);

                ArrayList<Person> array = new ArrayList<Person>();
                array.add(p1);
                array.add(p2);
                array.add(p3);
                array.add(p4);
               
                Iterator<Person> it = array.iterator();
                while(it.hasNext()){
                        sop(it.next());
                }
                //-------------------------------问题所在:又加了一个while语句,可是似乎没有执行...
                while(it.hasNext()){
                        sop(it.next());
                }
             //-----------------------------------------------------
        }
        //定义了一个打印方法,可以打印各种类型的数据。
        public static void sop(Object obj){
                System.out.println(obj);
        }
}
//自定义了一个Person类,因为它本身不像String类那样重写了toString()方法,所以我自己已经重写。
class Person
{
        private String name;
        private int age;
        Person(String name,int age){
                this.name=name;
                this.age=age;
        }
        public String getName(){
                return name;
        }
        public int getAge(){
                return age;
        }
        //重写了toString()方法
        public String toString() {
                return ""+ name +"--"+age;
        }
}

32 个回复

正序浏览
左脑想你 发表于 2014-10-8 22:15
谢啦。。。我已经不用了我上了45期

恩啊,已经上了就好,加油吧,有些晚了,不太好意思,我上了46期...
回复 使用道具 举报
依然超级赛亚人 发表于 2014-9-27 23:12
哥们,虽然感觉现在很晚,估计你都被黑马录取很久了,但是为了践行当初的诺言,我还是想问一下,你是不是 ...

谢啦。。。我已经不用了我上了45期
回复 使用道具 举报
因为迭代器里包含指针,当第一个循环while(it.hasNext())判断下一点是否有数据,然后打印it.next的时候指针就会往后移动一次,知道循环结束时指针就到了结尾,这样下一个循环while(it.hasNext())中it.hasNext()的返回值是false,因此不会进行第二个while循环
回复 使用道具 举报
左脑想你 发表于 2014-8-9 13:12
兄弟你要是先进黑马了给我留个亲友券。。。。我现在还在传智上基础班

哥们,虽然感觉现在很晚,估计你都被黑马录取很久了,但是为了践行当初的诺言,我还是想问一下,你是不是已经被录取了?还用亲友券吗?我现在有一张亲友券。我报的46期,29号才能下来成绩,所以之前也没有可用的亲友券给你,有点惭愧,要是用得到的话就招呼一声。
回复 使用道具 举报
依然超级赛亚人 发表于 2014-8-9 06:47
相当于第二个while和第一个while“连接”起来了,第一个while执行完毕后,后面没有元素了,第二个while也 ...

恩 因为遍历的时候List集合石油角标的 你while遍历第一遍的时候指针已经判断到尾了,Iterator有个子接口ListIterator 有个hasPrevious()方法可以到这再遍历一遍
回复 使用道具 举报
本帖最后由 依然超级赛亚人 于 2014-8-9 13:32 编辑
左脑想你 发表于 2014-8-9 13:12
兄弟你要是先进黑马了给我留个亲友券。。。。我现在还在传智上基础班

弱弱的说一句,我在准备8月底的,7月末在传智基础班毕业...现在我才走基础测试这个程序,估计不少比我晚毕业的都能赶到我前面,自己学的有点渣...不过,果真我有幸比哥们你早进去的话,有亲友券的话...对了,我还不知能进黑马的人有几张亲友券呢,之前已经有个同班的也说过你相同的话,我答应了,到最后如果只有一张的话那我可就为难了。这样吧,假如只有一张而且你们俩到时都需要的话(也许你们在我之前就进去了),我还是给他吧,虽然拒绝人挺不好的,但我也不能食言于提前打过招呼的哥们儿,你说对吧?如果他用不到,我就给你,一言为定!
回复 使用道具 举报
依然超级赛亚人 发表于 2014-8-9 06:44
嗯啊,我就在这个点上不知是哪种情况,不知判断到最后结束时指针是停在最后一个元素上还是回到初始位置, ...

兄弟你要是先进黑马了给我留个亲友券。。。。我现在还在传智上基础班
回复 使用道具 举报
liqi 发表于 2014-8-7 21:47
学习了,谢谢楼主的问题和大家的解答

互相学习,互相借鉴,一起探讨,大家彼此都不用客气。:lol
回复 使用道具 举报
继续悲伤 发表于 2014-8-7 20:50
你在第一次遍历完以后再添加元素试试!!

会发生ConcurrentModificationException(并发修改异常),因为这违反了“迭代器遍历,迭代器修改。集合遍历,集合修改”的原则,如果换成普通for或者增强for循环,然后用集合修改的话就失去了这道题原来的本质,想想是这样吗?:lol
回复 使用道具 举报

相当于第二个while和第一个while“连接”起来了,第一个while执行完毕后,后面没有元素了,第二个while也就不执行了,判断条件为false.
回复 使用道具 举报
左脑想你 发表于 2014-8-7 18:20
每一个next指针都会向后一个第一个循环过后指针在最后的位置,第二个循环的条件判断是指针还是在最后也就是 ...

嗯啊,我就在这个点上不知是哪种情况,不知判断到最后结束时指针是停在最后一个元素上还是回到初始位置,之前理解为自动回到第一个元素的位置处,现在经过大家的提醒已经知道了科问题所在。:handshake
回复 使用道具 举报

简单易懂,明白!:handshake
回复 使用道具 举报
zz_job 发表于 2014-8-7 17:28
因为第一个迭代器的指针已经指向集合的末尾了,因此你的第二个while循环实际上判断条件始终为假,因为it.ha ...

恩啊,经过大家这么一说我才明白:第一个while判断之后没有恢复成它判断之前的状态,也就是指针没有自动回到第一个元素前面,再写while自然就不执行了。:handshake
回复 使用道具 举报
icris 发表于 2014-8-7 16:49
第二个 while(it.hasNext()){} == while(false){}

回答的简单明了啊,程序在语义上确实是这么处理的。:handshake
回复 使用道具 举报
rolling-stone 发表于 2014-8-7 16:43
迭代器本质上是指针,迭代的时候指针不段的向后判断,你第一个while已经将指针移到最后面了,第二个while再 ...

开始我以为第一个while执行完毕后就恢复成原来的初始状态了,没有想到指针会呆在最后一个元素上,现在看来再写一个while是和原来的叠加了,所以没有元素可取了。:handshake
回复 使用道具 举报
怀念黑海岸 发表于 2014-8-7 21:50
楼上的同学们说的很对呢:你第一次执行完while循环后it对象的指针已经知道最后了,所以你第二次再执行it.ha ...

确实,我按照这个方式试了一下,结果打印了两次。第二次是逆向打印的,没想到出现的一个问题顺便把逆向遍历这个知识点也给体会了一下,呵呵。
回复 使用道具 举报
楼上的同学们说的很对呢:你第一次执行完while循环后it对象的指针已经知道最后了,所以你第二次再执行it.hasNext()肯定就没了。你可以在第一个while后面加一句System.out.println(it.hasNext());结果为false。
     如果你使用的是ListIterator的话那么你可以在第一次while结束后加上一个while反向迭代,
      ListIterator<Integer> it =list.listIterator();
      while(it.hasPrevious()){
                        System.out.print(it.previous());
这时候就可以再迭代一次。。
回复 使用道具 举报
学习了,谢谢楼主的问题和大家的解答
回复 使用道具 举报
依然超级赛亚人 发表于 2014-8-7 21:32
高手!确实是这样。我忽略了这一点,以为上面第一个while遍历之后,指针会自动恢复成初始情况下的状态, ...

:D我新手刚开始学呢  互相学习
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马