ArrayList学习心得:
看完ArrayList后感:
一、System.arraycopy比for循环赋值比clone速度在大小超过一定数目的时候要快。
class ArrayCopyTest { public static void main(String[] args) { new ArrayCopyTest().arrayCopy(); } Object[] srcArray1 = { "sdfsdaf", new Date(), new Integer(200) }; Object[] srcArray2 = { "qwerasd", new Date(), new Integer(190), srcArray1, new Object(), new String[] { "aaa", "bbb" } }; Object[] srcArray3 = new Object[30]; Object[] srcArray4 = new Object[150]; Object[] srcArray5 = new Object[300]; ArrayCopyTest() { fillArray(srcArray3); fillArray(srcArray4); fillArray(srcArray5); } /** * 填充对象数组。 * * @param objs * 填充目标。 */ private void fillArray(Object[] objs) { for (int i = 0; i < objs.length; i = i + 10) { fillArray(objs, i); } } void fillArray(Object[] objs, int start) { objs[start++] = new Object(); objs[start++] = new Date(); objs[start++] = getRandomString(); objs[start++] = getRandomString(); objs[start++] = getRandomString(); objs[start++] = getRandomString(); objs[start++] = getRandomString(); objs[start++] = r.nextLong(); objs[start++] = getRandomString(); objs[start++] = getRandomString(); } private Random r = new Random(); /** * 获取随机字符串。 * * @return 随机字符串 */ String getRandomString() { StringBuffer sb = new StringBuffer(); int loop = 3 + r.nextInt(4); while (loop > 0) { loop--; sb.append((char) (97 + r.nextInt(25))); sb.append((char) (65 + r.nextInt(25))); } return sb.toString(); } void arrayCopy() { testMethod("short array\t############", srcArray1); testMethod("long array\t########################", srcArray2); testMethod("big array\t####################################", srcArray3); testMethod( "huge array\t################################################", srcArray4); testMethod( "mass array\t############################################################", srcArray5); } /** * 成组测试。 * * @param prmpt * 测试提示 * @param args * 测试对象数组 */ void testMethod(String prmpt, Object[] args) { int loop = 5000000; System.out.println(prmpt); arrayClone(loop, args); arrayManualCopy(loop, args); arraySysCopy(loop, args); } void arrayClone(int loop, Object[] sourceArray) { long time = System.currentTimeMillis(); for (int i = 0; i < loop; ++i) { Object[] destArray = (Object[]) sourceArray.clone(); } System.out.println(" arrayClone\t" + (System.currentTimeMillis() - time)); } void arraySysCopy(int loop, Object[] sourceArray) { long time = System.currentTimeMillis(); for (int i = 0; i < loop; ++i) { Object[] destArray = new Object[sourceArray.length]; System.arraycopy(sourceArray, 0, destArray, 0, sourceArray.length); } System.out.println(" arraySysCopy\t" + (System.currentTimeMillis() - time)); } void arrayManualCopy(int loop, Object[] sourceArray) { long time = System.currentTimeMillis(); for (int i = 0; i < loop; ++i) { Object[] destArray = new Object[sourceArray.length]; for (int j = 0; j < sourceArray.length; ++j) { destArray[j] = sourceArray[j]; } } System.out.println(" arrayManulCopy\t" + (System.currentTimeMillis() - time)); } }
二、源码中private transient E[] elementData; 为什么把 elementData 设置为不参与序列化:
因为在ArrayList中是以数组的方式去实现的,而数组的大小是要大于等于所存数据的大小。而序列化的机制是:在序列化数组的时候,不管你的数组里面有没有存值,他只根据数组的大小去序列化,也就是说,如果你初始化了一个数组为10个大小,而你实际只在前3个里面放了值,那么在序列化的时候,他会把你初始的10个大小都写进序列化里面。然而那些超过的大小,并且是我们使用者所想要的,所以如果在序列化的时候全写里面,这样是不妥的,所以这里要声明为不可序列化!
有看不懂的,可以看下面的代码:
class SerializableTest { public static void main(String[] args) { String[] s = new String[10]; s[0] = "aaa"; s[1] = "bbb"; s[2] = "ccc"; s[3] = "ddd"; FileOutputStream os = new FileOutputStream("F:\\t.txt"); ObjectOutputStream oos = new ObjectOutputStream(os); for (int i = 0; i < s.length; i++) { oos.writeObject(s[i]); } oos.close(); String[] ss = new String[10]; FileInputStream is = new FileInputStream("F:\\t.txt"); ObjectInputStream ois = new ObjectInputStream(is); for(int i=0;i<ss.length;i++){ ss[i]=(String) ois.readObject(); } for(int i=0;i<ss.length;i++){ System.out.println(ss[i]); } ois.close(); } }
三、通过集合类的帮助类Collections.synchronizedList(new ArrayList (...))可以让这个ArrayList进行同步。
我在想,是不是Vector可以用不着了?因为Vector是强制性的同步,而ArrayList这个,是灵活性的同步!(求高手解决我心中的疑惑!)
以上是我学习ArrayList的心得。在此总结一下!