黑马程序员技术交流社区

标题: List集合list迭代器的疑问。 [打印本页]

作者: ppStudent    时间: 2014-11-28 13:26
标题: List集合list迭代器的疑问。
本帖最后由 ppStudent 于 2014-11-28 13:34 编辑

            有一个ArrayList<String>集合共有4个元素:"1234",“5678”,"9101",“1112”,现在我想要在将该集合拆分成单独的数字子串,比如"1234"就变成了'1','2','3','4',有下面几种错误,有些我理解,有些我不理解的 错误:
1、
  1. public class yiwen1
  2. {
  3.         public static void main()
  4.         {
  5.                 List<String> listA = new ArrayList<String>();
  6.                 listA.add("1234");
  7.                 listA.add("5678");
  8.                 listA.add("9101");
  9.                 listA.add("1112");
  10.                 listA=change1(listA);
  11.         }
  12.         public static List<String> change1(List<String> list)
  13.         {
  14.                 for(Iterator<String> it=list.iterator();it.hasNext()!=false;)
  15.                 {
  16.                         String str = it.next();
  17.                         char[] arr=str.toCharArray();//将每一个字符串转为字符数组
  18.                         for(int i=0;i<arr.length;i++)
  19.                         {
  20.                                 list.add(String.valueOf(arr[i]));//将每个字符存入集合
  21.                         }
  22.                         list.remove(str);//会出现ConcurrentModificationException异常
  23.                           //删除原有的元素,在通过Iterator进行遍历的时候,如果直接对list进行操作后,再继续用之前的Iterator进行遍历就会出现这个异常,表示其已经被修改
  24.                 }
  25.                 return list;
  26.         }
复制代码
会出现的错误已经很明显了,在迭代器内部是不能对调用该迭代器的对象进行直接操作的,要用迭代器来操作
2、这个有疑问:
  1. package com.itheima;
  2. import java.util.ArrayList;
  3. import java.util.Iterator;
  4. import java.util.List;
  5. import java.util.ListIterator;

  6. public class yiwen1
  7. {
  8.         public static void main(String[] args)
  9.         {
  10.                 List<String> listA = new ArrayList<String>();
  11.                 listA.add("1234");
  12.                 listA.add("5678");
  13.                 listA.add("9101");
  14.                 listA.add("1112");
  15.                 listA=change1(listA);
  16.                 System.out.println(listA);
  17.         }
  18.         public static List<String> change1(List<String> list)
  19.         {
  20.                 for(ListIterator<String> it=list.listIterator();it.hasNext()!=false;)
  21.                 {
  22.                         String str = it.next();
  23.                         char[] arr=str.toCharArray();//将每一个字符串转为字符数组
  24.                         for(int i=0;i<arr.length;i++)
  25.                         {
  26.                                 it.add(String.valueOf(arr[i]));//将每个字符存入集合
  27.                         }
  28.                         it.remove();//使用迭代器的操作集合方法
  29.                 }
  30.                 return list;
  31.         }
  32. }
复制代码
//这个不知道为什么是错的?3、又或者这样
  1. import java.util.*;

  2. public class yiwen1
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 List<String> listA = new ArrayList<String>();
  7.                 listA.add("1234");
  8.                 listA.add("5678");
  9.                 listA.add("9101");
  10.                 listA.add("1112");
  11.                 listA=change1(listA);
  12.                 System.out.println(listA);
  13.         }
  14.         public static List<String> change1(List<String> list)
  15.         {
  16.              for(ListIterator<String> it=list.listIterator();it.hasNext()!=false;)
  17.              {
  18.              it.add("22");//将每个字符存入集合
  19.              }
  20.              return list;
  21.         }
复制代码


作者: 返璞归真    时间: 2014-11-28 13:50
这么改就可以了,你的for循环好特别 0.0
public static List<String> change1(List<String> list) {
                for (ListIterator<String> it = list.listIterator(); it.hasNext() != false;) {
                        String str = it.next();
                        char[] arr = str.toCharArray();// 将每一个字符串转为字符数组
                        it.remove();// 使用迭代器的操作集合方法
                        for (int i = 0; i < arr.length; i++) {
                                it.add(String.valueOf(arr[i]));// 将每个字符存入集合
                        }
                }
                return list;
        }


你是在做送技术分的题吧,我写的这是,你可以参考下

ListExer.zip

13.96 KB, 下载次数: 276


作者: wangzheng406    时间: 2014-11-28 14:13
迭代器不该用List方法吧
作者: ppStudent    时间: 2014-11-28 14:42
返璞归真 发表于 2014-11-28 13:50
这么改就可以了,你的for循环好特别 0.0
public static List change1(List list) {
                for (ListIterator it ...

那道题目我做完了,我主要是有一些疑问。。
作者: ppStudent    时间: 2014-11-28 14:47
wangzheng406 发表于 2014-11-28 14:13
迭代器不该用List方法吧

那是我的问题1,我在下面写答案了,请看完了在回复,谢谢
作者: wtjohn    时间: 2014-11-28 17:07
本帖最后由 wtjohn 于 2014-11-28 17:20 编辑

有点迷糊

作者: wtjohn    时间: 2014-11-28 17:23
2当中的

it.add(String.valueOf(arr[i]));//将每个字符存入集合


有点搞不懂,listiterator的add是将对象加到arraylist的末尾吗? 如果不是,循环第二遍的时候it.next()又是指向哪里
作者: ppStudent    时间: 2014-11-28 17:39
wtjohn 发表于 2014-11-28 17:23
2当中的

it.add(String.valueOf(arr));//将每个字符存入集合

不不不,你要仔细看看javaapi,ListIterator的add()方法不是将其加到末尾,而是加到当前元素的前面,我的2写错了,应该讲it.remove()写在上面来
作者: cvnmklop    时间: 2014-11-28 18:33
本帖最后由 cvnmklop 于 2014-11-28 18:39 编辑


至于你的疑问我已经从java源代码中找到原因。
  1. /*
  2. ListIterator注意事项
  3. next将lastRet=i
  4. add和remove要注意顺序 因为add方法将lastRet=-1会导致remove出现异常
  5. */


  6. public class ArrayList<E> extends AbstractList<E>
  7.         implements List<E>, RandomAccess, Cloneable, java.io.Serializable{   
  8.    
  9.    public Iterator<E> iterator() {
  10.         return new Itr();
  11.     }
  12.         private class Itr implements Iterator<E> {
  13.         int cursor;       // index of next element to return
  14.         int lastRet = -1; // index of last element returned; -1 if no such 就是这个值导致的问题
  15.         int expectedModCount = modCount;

  16.                 @SuppressWarnings("unchecked")
  17.         public E next() {
  18.             checkForComodification();
  19.             int i = cursor;
  20.             if (i >= size)
  21.                 throw new NoSuchElementException();
  22.             Object[] elementData = ArrayList.this.elementData;
  23.             if (i >= elementData.length)
  24.                 throw new ConcurrentModificationException();
  25.             cursor = i + 1;
  26.             return (E) elementData[lastRet = i];
  27.         }
  28.                
  29.         public void remove() {
  30.             if (lastRet < 0)//当lastRet<0时就抛异常
  31.                 throw new IllegalStateException();
  32.             checkForComodification();

  33.             try {
  34.                 ArrayList.this.remove(lastRet);
  35.                 cursor = lastRet;
  36.                 lastRet = -1;
  37.                 expectedModCount = modCount;
  38.             } catch (IndexOutOfBoundsException ex) {
  39.                 throw new ConcurrentModificationException();
  40.             }
  41.         }

  42.         public void add(E e) {
  43.             checkForComodification();

  44.             try {
  45.                 int i = cursor;
  46.                 ArrayList.this.add(i, e);
  47.                 cursor = i + 1;
  48.                 lastRet = -1;//当迭代器添加完元素后就把这个值赋值为-1
  49.                 expectedModCount = modCount;
  50.             } catch (IndexOutOfBoundsException ex) {
  51.                 throw new ConcurrentModificationException();
  52.             }
  53.         }
  54.     }
  55. }
复制代码





作者: 康师傅-蛋黄派    时间: 2014-11-28 18:46
cvnmklop 发表于 2014-11-28 18:33
至于你的疑问我已经从java源代码中找到原因。

先加进来的数>=删除的数什么意思啊?下面的源代码有点看不懂,帮解释下呗
作者: 康师傅-蛋黄派    时间: 2014-11-28 18:48
ppStudent 发表于 2014-11-28 17:39
不不不,你要仔细看看javaapi,ListIterator的add()方法不是将其加到末尾,而是加到当前元素的前面,我的 ...

楼主,写上面和写下面什么区别呢?
作者: cvnmklop    时间: 2014-11-28 18:54
康师傅-蛋黄派 发表于 2014-11-28 18:46
先加进来的数>=删除的数什么意思啊?下面的源代码有点看不懂,帮解释下呗 ...

这个先加进来的那句话我已经删除了。看了源码以后才知道因为不会存在这个问题。因为迭代器一旦建立以后,里面元素的遍历已经是固定了。换句话说后面怎么加没关系迭代器还是按照原来元素来遍历。至于后面的代码是解决他的第二个疑问的。误导你了对不起
作者: kerner    时间: 2014-11-28 19:19
void remove()
从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。对于每个 next 或 previous 调用,只能执行一次此调用。只有在最后一次调用 next 或 previous 之后,尚未调用 ListIterator.add 时才可以执行该调用。

作者: scoto263    时间: 2014-11-28 20:15
老师出的题目,答案都被你贴出来了。。呵呵,,这题我也做完了,来看看你的代码
作者: ppStudent    时间: 2014-11-28 21:29
scoto263 发表于 2014-11-28 20:15
老师出的题目,答案都被你贴出来了。。呵呵,,这题我也做完了,来看看你的代码 ...

呵呵,好像我漏题了似的,这一问基本都能做出来的好么,我主要是有些疑问需要解答而已




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