原文地址:http://linuxlong.iteye.com/blog/651469
首先,提醒下:
Arrays.asList 转化为的list。它和new ArrayList出来的对象不一样
例如在: list.remove时候,数组转化来的容易出错,new ArrayList() 更安全点!.
其他:
懒程序员,在代码越写越多的情况下,总想着使用把代码精简一下,能不写if else的,能不写for循环的尽量不想写,但是遇到的问题都要解决的呀,因此调用同逻辑的已存在方法便是首选。
今天就集合类(List)两个容易出错的方法做个记录,可以引以为戒,并且也提供正常的使用方式, 都是在java.utils包,方便使用。
Java代码
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. }
package com.longer.list;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
/**
*
* @author Longer
* Apr 23, 2010 2:49:13 PM
*/
public class ListTest extends TestCase {
class TempBean{
public TempBean( String str ){
this.str = str;
}
String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
List<TempBean> tempList = null;
protected void setUp() throws Exception {
super.setUp();
tempList = new ArrayList<TempBean>();
tempList.add( new TempBean("1") );
tempList.add( new TempBean("2") );
tempList.add( new TempBean("30") );
tempList.add( new TempBean("31") );
tempList.add( new TempBean("3") );
}
protected void tearDown() throws Exception {
super.tearDown();
tempList.clear();
tempList = null;
}
public void testRemove1(){
for (TempBean bean : tempList ) {
//exception:java.util.ConcurrentModificationException
//tempList.remove( bean );
}
System.out.println( tempList );
}
public void testRemove2(){
for (int i = 0; i < tempList.size(); i++) {
TempBean bean = tempList.get(i);
tempList.remove( i );//or tempList.remove(bean);
i--;
}
System.out.println( tempList );
}
public void testRemove3(){
System.out.println("before remove:" + tempList );
for (Iterator iterator = this.tempList.iterator(); iterator.hasNext();) {
iterator.remove();
//exception:java.lang.IllegalStateException
//tempList.add( new TempBean("") );
}
System.out.println("after remove:"+ tempList );
}
public void testCopy1(){
List<TempBean> newList = new ArrayList<TempBean>();
//exception:java.lang.IndexOutOfBoundsException: Source does not fit in dest
//Collections.copy( newList, tempList );
}
public void testCopy2(){
List<TempBean> newList = new ArrayList<TempBean>(Arrays.asList(new TempBean[ this.tempList.size()]));
Collections.copy( newList, tempList );
System.out.println( newList );
}
}
异常解释:
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()值等长(或更长)
首先,提醒下:
Arrays.asList 转化为的list。它和new ArrayList出来的对象不一样
例如在: list.remove时候,数组转化来的容易出错,new ArrayList() 更安全点!.
其他:
懒程序员,在代码越写越多的情况下,总想着使用把代码精简一下,能不写if else的,能不写for循环的尽量不想写,但是遇到的问题都要解决的呀,因此调用同逻辑的已存在方法便是首选。
今天就集合类(List)两个容易出错的方法做个记录,可以引以为戒,并且也提供正常的使用方式, 都是在java.utils包,方便使用。
Java代码
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. }
package com.longer.list;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
/**
*
* @author Longer
* Apr 23, 2010 2:49:13 PM
*/
public class ListTest extends TestCase {
class TempBean{
public TempBean( String str ){
this.str = str;
}
String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
List<TempBean> tempList = null;
protected void setUp() throws Exception {
super.setUp();
tempList = new ArrayList<TempBean>();
tempList.add( new TempBean("1") );
tempList.add( new TempBean("2") );
tempList.add( new TempBean("30") );
tempList.add( new TempBean("31") );
tempList.add( new TempBean("3") );
}
protected void tearDown() throws Exception {
super.tearDown();
tempList.clear();
tempList = null;
}
public void testRemove1(){
for (TempBean bean : tempList ) {
//exception:java.util.ConcurrentModificationException
//tempList.remove( bean );
}
System.out.println( tempList );
}
public void testRemove2(){
for (int i = 0; i < tempList.size(); i++) {
TempBean bean = tempList.get(i);
tempList.remove( i );//or tempList.remove(bean);
i--;
}
System.out.println( tempList );
}
public void testRemove3(){
System.out.println("before remove:" + tempList );
for (Iterator iterator = this.tempList.iterator(); iterator.hasNext();) {
iterator.remove();
//exception:java.lang.IllegalStateException
//tempList.add( new TempBean("") );
}
System.out.println("after remove:"+ tempList );
}
public void testCopy1(){
List<TempBean> newList = new ArrayList<TempBean>();
//exception:java.lang.IndexOutOfBoundsException: Source does not fit in dest
//Collections.copy( newList, tempList );
}
public void testCopy2(){
List<TempBean> newList = new ArrayList<TempBean>(Arrays.asList(new TempBean[ this.tempList.size()]));
Collections.copy( newList, tempList );
System.out.println( newList );
}
}
异常解释:
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()值等长(或更长)