黑马程序员技术交流社区

标题: 不理解ListIterator中多个修改语句顺序不同出现的异常 [打印本页]

作者: 崔维友    时间: 2012-11-22 11:28
标题: 不理解ListIterator中多个修改语句顺序不同出现的异常
本帖最后由 崔维友 于 2012-11-22 12:21 编辑

        Iterator只能对集合元素判断、读取、删除操作。使用ListIteraotr可以进行增、删、改、查的操作。但在多个不同的操作中,因为顺序不同而抛出异常IllegalStateException。
        API中的说明是“在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。”对这句话不慎理解。
        代码:
  1. import java.util.*;

  2. class ListDemo2
  3. {
  4.         public static void getColl(Object obj)
  5.         {
  6.                 System.out.println(obj);
  7.         }

  8.         public static void main(String[] args)
  9.         {
  10.                 //List的子类ArrayList
  11.                 ArrayList alt=new ArrayList();
  12.                 alt.add("ArrayList1");
  13.                 alt.add("ArrayList2");
  14.                 alt.add("ArrayList3");
  15.                 alt.add("ArrayList4");
  16.                 getColl("原     集      合:"+alt);
  17. /*
  18.                 //迭代修改,仅用于List对象。不能使用集合和迭代器同时操作容器
  19.                 for (ListIterator lt=alt.listIterator(); lt.hasNext(); )
  20.                 {
  21.                         Object obj=lt.next();
  22.                         if (obj.equals("ArrayList3"))
  23.                         {
  24.                                 lt.add("Hello");
  25.                                 lt.add("World");
  26.                                 lt.set("Vigiles");        //放在第三句执行为何抛出异常
  27.                         }
  28.                 }
  29.                 getColl("迭代器for添加:"+alt);
  30. */
  31.                 //迭代修改,仅用于List对象。不能使用集合和迭代器同时操作容器
  32.                 for (ListIterator lt=alt.listIterator(); lt.hasNext(); )
  33.                 {
  34.                         Object obj=lt.next();
  35.                         if (obj.equals("ArrayList3"))
  36.                         {
  37.                                 lt.set("Vigiles");
  38.                                 lt.add("Hello");
  39.                                 lt.add("World");
  40.                         }
  41.                 }
  42.                 getColl("迭代器for添加:"+alt);
  43.         }
  44. }
复制代码

-------------------------------------------------------------
请各位不吝赐教!




作者: 梁小波    时间: 2012-11-22 12:06
刚看完这个问题觉得很有意思。
细想一下,首先我们知道add和set的作用。
1.add会在当前next所取值的后面添加元素,注意有一个隐含操作:就是你的“指针”向后移一位。(这句话就是说把调用 nextIndex  所返回的值增加 1),那么你的下一次next调用就会取到下一个值!
2.set的作用是把当前next返回的值。前提是只有在最后一次调用 next 或 previous 后既没有调用 ListIterator.remove 也没有调用 ListIterator.add 时才可以进行该调用。

这引用了api里面的一些话。
我觉得再用set时候不让先用add或者remove是由于会影响”指针“的位置。先进行add会把”指针“加1。另外api中明确说remove也必须在没有使用add之前使用。
可能是内部机制决定了,如果你学习过c语言,并且练习过数据结构的链表,这个迭代器应该是单向链表,应该是set时候会用到前一个指针,当add后指针变换,就使得前一个指针变换了,不是我们想要的结果。

我觉得有点不是表述的很明白,你真的就按数据结构的链表方法思考一下,我觉得是这样,不知对否。
另外这些在api中都是有明确规定的,不去看背后的机制的话,就当成一个规定吧。呵呵。
作者: 崔维友    时间: 2012-11-22 12:20
本帖最后由 崔维友 于 2012-11-22 12:22 编辑
梁小波 发表于 2012-11-22 12:06
刚看完这个问题觉得很有意思。
细想一下,首先我们知道add和set的作用。
1.add会在当前next所取值的后面添 ...

        的确如梁老师所说,set方法只有在最后一次调用 next 或 previous 后既没有调用 ListIterator.remove 也没有调用 ListIterator.add 时才可以进行调用。如果能仔细看看API就不必如此劳烦。
        非常感谢你的指教!
ps:
梁老师的学习状态很棒,羡慕!
感谢评分的老师!




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