黑马程序员技术交流社区

标题: 复写fill的时候的问题[已解决] [打印本页]

作者: 王自强    时间: 2012-9-1 00:04
标题: 复写fill的时候的问题[已解决]
本帖最后由 王自强 于 2012-9-2 17:22 编辑

  1. import java.util.*;
  2. class demo
  3. {
  4.         public static void sop(Object obj)
  5.         {
  6.                 System.out.println(obj);
  7.         }
  8.         public static void main(String[] args)
  9.         {
  10.                
  11.                 List<String> list = new ArrayList<String>();
  12.                 list.add("a");list.add("a");list.add("a");
  13.                 list.add("a");list.add("a");list.add("a");
  14.                
  15.                 sop(list);
  16.                 tihuan(list,3,5,"b");
  17.                 sop(list);
  18.         }
  19.         //实现对List集合中指定元素的替换
  20.         public static <T>void tihuan(List<T> list,int start, int end,T obj)
  21.         {
  22.                
  23.                
  24.                 List<T> sublist1 = list.subList(0,start);
  25.                 List<T> sublist2 = list.subList(start,end);
  26.                 List<T> sublist3 = list.subList(end,list.size());
  27.                 Collections.fill(sublist2,obj);

  28.                 list.clear();
  29.                 list.addAll(sublist1);//? 错哪了?
  30.                 list.addAll(sublist2);//?
  31.                 list.addAll(sublist3);//?                        

  32.                 /*for(int x = start;x<end;x++)
  33.                         list.set(x,obj);
  34.                 */
  35.         }
  36. }
复制代码
代码运行时有问题,不知道这种方法错哪了?


作者: 郑义    时间: 2012-9-1 08:35
楼主的问题主要在下边这几行代码:
  1. List<T> sublist1 = list.subList(0,start);
  2. List<T> sublist2 = list.subList(start,end);
  3. List<T> sublist3 = list.subList(end,list.size());
  4. Collections.fill(sublist2,obj);

  5. list.clear();
  6. list.addAll(sublist1);//? 错哪了?
  7. list.addAll(sublist2);//?
  8. list.addAll(sublist3);//?
复制代码
首先可以知道这个异常是并发修改异常。其问题就在于代码前后的联系。
比如,你已经执行了
List<T> sublist1 = list.subList(0,start);
List<T> sublist2 = list.subList(start,end);
List<T> sublist3 = list.subList(end,list.size());
Collections.fill(sublist2,obj);
这几句,但是当你执行完了list.clear();这句后,list本身已经清空。
但是sublist1,sublist2和sublist3都是list的子集合。所以当list改变之后实际上子集合也应该改变。
但是这样Java虚拟机就不知道你所需要的子集合是什么了,所以就会报出并发修改异常。
即使把list.clear();去掉,
list.addAll(sublist1);
list.addAll(sublist2);
list.addAll(sublist3);
这三句也在修改list集合,所以也会报出并发修改异常。
所以只要重新定义一个新的list集合,这个程序就可以正常运行了。
代码:
  1. import java.util.*;
  2. class Test1
  3. {
  4. public static void sop(Object obj)
  5. {
  6. System.out.println(obj);
  7. }
  8. public static void main(String[] args)
  9. {
  10. List<String> list = new ArrayList<String>();
  11. list.add("a");list.add("a");list.add("a");
  12. list.add("a");list.add("a");list.add("a");

  13. sop(list);
  14. list = tihuan(list,3,5,"b");

  15. sop(list);
  16. }
  17. //实现对List集合中指定元素的替换
  18. public static<T> List<T> tihuan(List<T> list,int start, int end,T obj)
  19. {
  20. List<T> newlist = new ArrayList<T>();
  21. List<T> sublist1 = list.subList(0,start);
  22. List<T> sublist2 = list.subList(start,end);
  23. List<T> sublist3 = list.subList(end,list.size());
  24. Collections.fill(sublist2,obj);
  25. newlist.addAll(sublist1);
  26. newlist.addAll(sublist2);
  27. newlist.addAll(sublist3);
  28. return newlist;
  29. }
  30. }
复制代码
这样,建立新的list之后就不会对list和list的字串进行修改,就不会产生并发修改异常


作者: AngieFans85    时间: 2012-9-1 13:35
郑义同学是正解.




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