[关闭]
@lzb1096101803 2016-03-12T10:25:24.000000Z 字数 1960 阅读 499

ArrayList Vector LinkedList 序列化

电话面试


1) Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
2) 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
3) Vector可以设置增长因子,而ArrayList不可以

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 二分查找用这个
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

ArrayList为什么可以序列化

ArrayList里面的数组elementData是声明为transient的,表示ArrayList在序列化的时候,默认不会序列化这些数组元素,因为ArrayList实际上是动态数组,每次在放满以后自动增长设定的长度值,如果数组自动增长长度设为100,而实际只放了一个元素,那就会序列化很多null元素,所以ArrayList把元素数组设置为transient。

对象实现java.io.Serializable接口以后,序列化的动作不仅取决于对象本身,还取决于执行序列化的对象。

声明为transient,为什么还可以序列化成功呢?
我的回答是ArrayList重写了writeObject方法
比较靠谱的原因是:
ArrayList是会开辟多余空间来保存数据的,而系列化和反序列化这些没有存放数据的空间是要消耗更多资源的,所以ArrayList的数组就声明为transient,自己实现write/readObject方法,仅仅系列化已经存放的数据

  1. /**
  2. * Save the state of the <tt>ArrayList</tt> instance to a stream (that
  3. * is, serialize it).
  4. *
  5. * @serialData The length of the array backing the <tt>ArrayList</tt>
  6. * instance is emitted (int), followed by all of its elements
  7. * (each an <tt>Object</tt>) in the proper order.
  8. */
  9. private void writeObject(java.io.ObjectOutputStream s)
  10. throws java.io.IOException{
  11. // Write out element count, and any hidden stuff
  12. int expectedModCount = modCount;
  13. s.defaultWriteObject();
  14. // Write out size as capacity for behavioural compatibility with clone()
  15. s.writeInt(size);
  16. // Write out all elements in the proper order.
  17. for (int i=0; i<size; i++) {
  18. s.writeObject(elementData[i]);
  19. }
  20. if (modCount != expectedModCount) {
  21. throw new ConcurrentModificationException();
  22. }
  23. }

错误的说法

ArrayList实现了java.io.Serializable接口,所以ArrayList对象可以序列化到持久存储介质中。
* private static final long serialVersionUID = 8683452581122892189L;
* private transient Object elementData[];
* private int size;

可以看出serialVersionUID和size都将自动序列化到介质中,但elementData数组对象却定义为transient了。
也就是说 ArrayList中的所有这些元素都不会自动系列化到介质中。为什么要这样实现?因为elementData数组中存储的
“元素”其实仅是对这些元素的一个引用,并不是真正的对象,序列化一个对象的引用是毫无意义的,因为序列化是为了
反序列化,当你反序列化时,这些对象的引用已经不可能指向原来的对象了。所以在这儿需要手工的对ArrayList的元素进
行序列化操作。这就是writeObject()的作用。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注