有点时间,看看泛型的实现。发现java中ArrayList原来效率真的不是很高。
整个ArrayList里面就是维护一个数组和一个int型的size大小。
private transient E[] elementData;
无论是add或者是remove,都是通过System.arraycopy实现的。
add的时候如果数组空间不够,是一个重复申请数组的过程。
remove是一个将数据组元素依次在数组中往前移动的循环。
add和remove都是调用了System.arraycopy。
下面是一段比较典型的代码,ensureCapacity检查数组空间是不是足够。System.arraycopy实现元素的移动。
/** * Appends all of the elements in the specified collection to the end of * this list, in the order that they are returned by the * specified collection's Iterator. The behavior of this operation is * undefined if the specified collection is modified while the operation * is in progress. (This implies that the behavior of this call is * undefined if the specified collection is this list, and this * list is nonempty.) * * @param c collection containing elements to be added to this list * @return <tt>true</tt> if this list changed as a result of the call * @throws NullPointerException if the specified collection is null */ public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }
ArrayList实现了java.io.Serializable接口,数组的transient标示这个属性不需自动序列化.这是因为elementData数组中存储的"元素"其实只是对这些元素的一个引用,并不是真正的对象,序列化没有意义.因为序列化是为了反序列化,当你反序列化时,这些对象的引用已经不可能指向原来的对象了.所以要手工对ArrayList的元素进行序列化操作,这就是writeObject()的作用。
/** * Save the state of the <tt>ArrayList</tt> instance to a stream (that * is, serialize it). * * @serialData The length of the array backing the <tt>ArrayList</tt> * instance is emitted (int), followed by all of its elements * (each an <tt>Object</tt>) in the proper order. */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff int expectedModCount = modCount; s.defaultWriteObject(); // Write out array length s.writeInt(elementData.length); // Write out all elements in the proper order. for (int i=0; i<size; i++) s.writeObject(elementData[i]); if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } }
在writeObject的时候可以看出来变量的作用:
throw new ConcurrentModificationException();
在一定的位置进行对修改的同步检查,如果修改次数大于本次修改之前的修改次数,那么说明在修改过程中,list可能被其他线程修改了。从而抛出异常。
在Vector类中,随处可见synchronized关键字。Vector是线程安全的。在每次操作的时候,强制进行同步。但是synchronized关键字强制进行同步,效率会很低。除了同步这一点,好像跟ArrayList没有太大区别。