黑马程序员技术交流社区

标题: 为什么抛异常 [打印本页]

作者: 孙飞    时间: 2012-7-5 14:26
标题: 为什么抛异常
本帖最后由 feigecal 于 2012-7-5 15:37 编辑

下面的代码会抛异常
  1. import java.util.*;
  2. class QuChongFu
  3. {
  4. public static void sop(Object obj)
  5. {
  6. System.out.println(obj);
  7. }
  8. public static void main(String[] args)
  9. {
  10. ArrayList al=new ArrayList();
  11. al.add("ok1");
  12. al.add("ok2");
  13. al.add("ok3");
  14. al.add("ok1");
  15. al.add("ok3");
  16. sop(al);
  17. sop(quChong(al));
  18. }
  19. public static ArrayList quChong(ArrayList al)
  20. {
  21. ArrayList nl=new ArrayList();
  22. ListIterator li=al.listIterator();
  23. while(li.hasNext())
  24. {
  25. if(!(nl.contains(li.next())))
  26. nl.add(li.next());
  27. }
  28. return nl;
  29. }
  30. }
复制代码
如果把while里的语句改成
  1. while(li.hasNext())
  2. {
  3. Object obj=li.next();
  4. if(!(nl.contains(obj)))
  5. nl.add(obj);
  6. }
  7. return nl;
复制代码
就正常运行,为什么要先赋给obj呢,有什么区别吗?


作者: 余清兰    时间: 2012-7-5 14:45
本帖最后由 余清兰 于 2012-7-5 14:47 编辑

因为在迭代元素的时候,并不知道返回的是什么类型的数据,所以要用Object obj类型来接收,也就是向上转型,obj能接收所有任意类型的数据
作者: 黑马刘洋    时间: 2012-7-5 14:48
23.while(li.hasNext())
24.{
25.if(!(nl.contains(li.next())))
26.nl.add(li.next());
27.}
你这里面运行了两次方法.next相当于进行了两次迭代。
所以应该在hasNext判断后面,先把next迭代到的这个元素存下来(存到Object 变量内),然后再进行操作。
这样既防止了两次调用方法,迭代两次,的错误了。
作者: 万宝东    时间: 2012-7-5 15:13
这是因为 li.next(); 会将li 返回当前元素,并且指向下一个元素,即执行了一次,下次在执行 li.next()返回的就是下一个元素了。
if(!(nl.contains(li.next())))
nl.add(li.next()); //这里执行了两次next(),却没有进行判断 hasNext(),当上一次next() 已经到达li 尾部时,这里当然就要报错了。
第一次判断的时候: if (!(nl.contains(li.next()))),迭代器下标(姑且如此理解)会移动到0,
然后判断为true,进入:nl.add(li.next());,这里又调用了next方法,迭代器下标会移动到1。
然后进入下个循环,进行判断的时候,迭代器下标已经是2了。少判断下标为1的。
等你每次循环,迭代器都向后移动了两次。。。
li.next方法你理解的不好。调用此方法是取迭代器中下一个元素,迭代器下标+1。
li.hasNext 是是否有下个元素,迭代器下标不变。
while(li.hasNext())

{

Object obj=li.next();

if(!(nl.contains(obj)))

nl.add(obj);

}

return nl;
修改完之后 ,li.next,缓存到一个变量。判断,然后添加到 最后结果。这样每个循环只调用一次 next(每过一个循环,迭代器下标+1),符合要求 。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2