Loading

Java List Copy,Remove容易出现的问题

主题:List删除元素,复制元素

平台:Window + Eclipse3.3 + JDK6

 

      懒程序员,在代码越写越多的情况下,总想着使用把代码精简一下,能不写if else的,能不写for循环的尽量不想写,但是遇到的问题都要解决的呀,因此调用同逻辑的已存在方法便是首选。

 

  今天就集合类(List)两个容易出错的方法做个记录,可以引以为戒,并且也提供正常的使用方式, 都是在java.utils包,方便使用。

 

 1 package com.longer.list;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Arrays;
 5 import java.util.Collections;
 6 import java.util.Iterator;
 7 import java.util.List;
 8 
 9 import junit.framework.TestCase;
10 
11 /**
12  * 
13  * @author Longer
14  * Apr 23, 2010 2:49:13 PM
15  */
16 public class ListTest extends TestCase {
17 
18     class TempBean{
19         
20         public TempBean( String str ){
21             this.str = str;
22         }
23         
24         String str;
25 
26         public String getStr() {
27             return str;
28         }
29 
30         public void setStr(String str) {
31             this.str = str;
32         }
33     }
34     
35     List<TempBean> tempList = null;
36     protected void setUp() throws Exception {
37         super.setUp();
38         
39         tempList = new ArrayList<TempBean>();
40         tempList.add( new TempBean("1") );
41         tempList.add( new TempBean("2") );
42         tempList.add( new TempBean("30") );
43         tempList.add( new TempBean("31") );
44         tempList.add( new TempBean("3") );
45     }
46 
47     protected void tearDown() throws Exception {
48         super.tearDown();
49         
50         tempList.clear();
51         tempList = null;
52     }
53     
54     public void testRemove1(){
55         
56         for (TempBean bean : tempList ) {
57             //exception:java.util.ConcurrentModificationException
58             //tempList.remove( bean );
59         }
60         System.out.println( tempList );
61     }
62     
63     public void testRemove2(){
64         
65         for (int i = 0; i < tempList.size(); i++) {
66             TempBean bean = tempList.get(i);
67             tempList.remove( i );//or tempList.remove(bean);
68             i--;
69         }
70         System.out.println( tempList );
71     }
72     
73     public void testRemove3(){
74         
75         System.out.println("before remove:" + tempList );
76         for (Iterator iterator = this.tempList.iterator(); iterator.hasNext();) {
77             iterator.remove();
78             //exception:java.lang.IllegalStateException
79             //tempList.add( new TempBean("") );
80         }
81         System.out.println("after remove:"+ tempList );
82     }
83     
84     public void testCopy1(){
85         
86         List<TempBean> newList = new ArrayList<TempBean>();
87         //exception:java.lang.IndexOutOfBoundsException: Source does not fit in dest
88         //Collections.copy( newList, tempList );
89     }
90     
91     public void testCopy2(){
92         
93         List<TempBean> newList = new ArrayList<TempBean>(Arrays.asList(new TempBean[ this.tempList.size()]));
94         Collections.copy( newList, tempList );
95         System.out.println( newList );
96     }
97 }

  异常解释:

 

  1:testRemove1-->java.util.ConcurrentModificationException

  此类的JavaDOC部分原文:

    This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible。

  简单翻译:

      检测到一个对象存在同步修改,并且此修改不被允许的情况下,此异常将被方法抛出。

 

  因此, 可以看出List是不支持同步修改的,其实整个Collection、Map都与List一样的情况,详细的原因得从迭代器Iterator去研究,这里不做分析。大概理解是Iterator在遍历的时间内,其源对象索引发生了改变,导致了不同步现象。

 

  2)testRemove3-->java.lang.IllegalStateException

  此类的JavaDOC部分原文:

    Signals that a method has been invoked at an illegal or inappropriate time

  简单翻译:

    信息灯,一个方法在非法或者不恰当的时间内被调用。

  因此, 问题的根源同上。

 

  3)testCopy1-->java.lang.IndexOutOfBoundsException

  Collections.copy JavaDOC部分原文:

    ......The destination list must be at least as long as the source list.......

  简单翻译:

    目的list必须至少要与源list等长。(目的List可以比源List长度长)

 

  因此, 它这里指的长度是List里的size()方法值,我们都知道new ArrayList()初始化的时候size()等于0,即便是你使用new ArrayList(10)来初始化,也只是预设了一个initialCapacity==10的存储空间,size()还是等于0。因此在使用Collections.copy之前,需要把目的List加一些空的元素,直到目的List的size()值与源List的size()值等长(或更长)。

 

原文链接:http://linuxlong.iteye.com/blog/651469

posted @ 2014-03-26 23:01  dai.sp  阅读(859)  评论(0编辑  收藏  举报