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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 依然超级赛亚人 高级黑马   /  2014-8-7 16:06  /  3358 人查看  /  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 个回复

倒序浏览
楼主可以尝试下再用add方法加入一个元素,看看有没有抛异常
回复 使用道具 举报
这个是因为迭代器指针问题。指针第一次已经运行到迭代器的最末尾位置,当第二次循环再次询问是否有hasNext的时候,肯定是没有元素的。List的迭代器有个向前遍历的方法,hasPrevious(),当指针运行到末尾时,问前面是否有元素,前面就有了。你可以试下,就可以打印两遍了。
回复 使用道具 举报 1 0
迭代器本质上是指针,迭代的时候指针不段的向后判断,你第一个while已经将指针移到最后面了,第二个while再循环,指针还是在最后,所以不会执行循环体的.
回复 使用道具 举报
第二个 while(it.hasNext()){} == while(false){}
回复 使用道具 举报
因为第一个迭代器的指针已经指向集合的末尾了,因此你的第二个while循环实际上判断条件始终为假,因为it.hasNext()的值已经被第一个while循环判定为假并终止循环,那么第二个循环一接收到就已经是假了  自然就不会再运行了。
回复 使用道具 举报
嗯 指针走弯了
  1.   Iterator<Person> it = array.iterator();
  2.                 while(it.hasNext())
  3.                                 {
  4.                         sop(it.next());
  5.                 }
  6.               //-----------------------------
  7.               System.out.println(it.hasNext());
  8.                  执行候是false
复制代码
回复 使用道具 举报
左脑想你 来自手机 中级黑马 2014-8-7 18:20:25
8#
每一个next指针都会向后一个第一个循环过后指针在最后的位置,第二个循环的条件判断是指针还是在最后也就是it.hasnext()为false所以不会进入第二个while循环
回复 使用道具 举报
就像同步了一样
回复 使用道具 举报
你在第一次遍历完以后再添加元素试试!!
回复 使用道具 举报
陶圣虎 发表于 2014-8-7 16:17
这个是因为迭代器指针问题。指针第一次已经运行到迭代器的最末尾位置,当第二次循环再次询问是否有hasNext ...

回答的很对。学到了,第二个while(it.hasNext)//为false,执行不到了用hasPrevious倒着取一次不就两次了,嘿嘿
回复 使用道具 举报
暗夜星辰 发表于 2014-8-7 16:14
楼主可以尝试下再用add方法加入一个元素,看看有没有抛异常

恩啊,问题已经解决了,就如楼下所说,这是指针的问题,我忽略了这一点,以为上面遍历之后,指针会自动恢复成原来的情况。:handshake
回复 使用道具 举报
陶圣虎 发表于 2014-8-7 16:17
这个是因为迭代器指针问题。指针第一次已经运行到迭代器的最末尾位置,当第二次循环再次询问是否有hasNext ...

高手!确实是这样。我忽略了这一点,以为上面第一个while遍历之后,指针会自动恢复成初始情况下的状态,看来指针是停在了最后一个元素上。
回复 使用道具 举报
rolling-stone 发表于 2014-8-7 16:43
迭代器本质上是指针,迭代的时候指针不段的向后判断,你第一个while已经将指针移到最后面了,第二个while再 ...

恩啊,问题就如大家所说,下面再接一个while遍历的话,相当于在第一个的基础上继续向后判断,此时确实已经没有元素可取。:handshake
回复 使用道具 举报
依然超级赛亚人 发表于 2014-8-7 21:32
高手!确实是这样。我忽略了这一点,以为上面第一个while遍历之后,指针会自动恢复成初始情况下的状态, ...

:D我新手刚开始学呢  互相学习
回复 使用道具 举报
学习了,谢谢楼主的问题和大家的解答
回复 使用道具 举报
楼上的同学们说的很对呢:你第一次执行完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:50
楼上的同学们说的很对呢:你第一次执行完while循环后it对象的指针已经知道最后了,所以你第二次再执行it.ha ...

确实,我按照这个方式试了一下,结果打印了两次。第二次是逆向打印的,没想到出现的一个问题顺便把逆向遍历这个知识点也给体会了一下,呵呵。
回复 使用道具 举报
rolling-stone 发表于 2014-8-7 16:43
迭代器本质上是指针,迭代的时候指针不段的向后判断,你第一个while已经将指针移到最后面了,第二个while再 ...

开始我以为第一个while执行完毕后就恢复成原来的初始状态了,没有想到指针会呆在最后一个元素上,现在看来再写一个while是和原来的叠加了,所以没有元素可取了。:handshake
回复 使用道具 举报
icris 发表于 2014-8-7 16:49
第二个 while(it.hasNext()){} == while(false){}

回答的简单明了啊,程序在语义上确实是这么处理的。:handshake
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马