Vector和ArrayList非常相似,两者都是用来表示可变数组,内部元素的存储都是通过数组来实现,可以随机的访问某个元素。
两者的主要区别是Vector的方法带有synchronized标志,各方法的访问是同步的,因此,Vector能够支持多线程,但是相应地效率比较低;ArrayList的方法没有synchronized标志,不是线程安全的。还有个比较小的差异是Vector在容量不够时,选择 size * 2扩容;ArrayList选择 size * 3/2 + 1扩容。
下面先来看下ArrayList的源码:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
RandomAccess: 这个是标记接口,没有需要实现的方法,声明ArrayList可以随机访问
Cloneable:ArrayList支持拷贝
Serializable: ArrayList支持序列化
ArrayList定义了如下的数组对象:
/** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. */ private transient Object[] elementData;
ArrayList使用elementData数组来缓存元素,使用transient关键字说明该数组对象不会被默认序列化,,开始很困惑,既然声明了ArrayList是可序列化的,为什么数组对象又声明为不能被序列化的?
/** * 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(); } } /** * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is, * deserialize it). */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); // Read in array length and allocate array int arrayLength = s.readInt(); Object[] a = elementData = new Object[arrayLength]; // Read in all elements in the proper order. for (int i=0; i<size; i++) a[i] = s.readObject(); }
因为ArrayList自定义了writeObject和readObject的方法,在writeObject中循环elementData数组序列化ArrayList中的元素。 可是为啥要这么折腾呢?
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } }
在创建ArrayList对象的时候,如果没有指定大小,默认ArrayList的size为10;在添加元素的时候,如果当前空间不足,会按照上面的ensureCapacity的方法来扩容,扩容后的大小是原先的1.5倍。因此elementData数组很可能没有放满,会有很多无效的null元素,默认的序列化会把无效的null元素也序列化,影响效率。
public E get(int index) { RangeCheck(index); return (E) elementData[index]; } public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; } public E remove(int index) { RangeCheck(index); modCount++; E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work return oldValue; }
上面是ArrayList的常见的方法,可以看到,实质上就是做些数组的操作。
下面先来看下Vector的源码:
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Vector的声明跟ArrayList一样,也是实现了List<E>, RandomAccess, Cloneable, java.io.Serializable这几个接口。
private void ensureCapacityHelper(int minCapacity) { int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object[] oldData = elementData; int newCapacity = (capacityIncrement > 0) ? (oldCapacity + capacityIncrement) : (oldCapacity * 2); if (newCapacity < minCapacity) { newCapacity = minCapacity; } elementData = Arrays.copyOf(elementData, newCapacity); } }
上面是Vector的扩容方法,当空间不足时,会分配 size * 2的空间。
public synchronized E elementAt(int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } return (E)elementData[index]; } public synchronized void addElement(E obj) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = obj; } public synchronized void removeElementAt(int index) { modCount++; if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } else if (index < 0) { throw new ArrayIndexOutOfBoundsException(index); } int j = elementCount - index - 1; if (j > 0) { System.arraycopy(elementData, index + 1, elementData, index, j); } elementCount--; elementData[elementCount] = null; /* to let gc do its work */ }
上面是Vector的常见的方法,跟ArrayList的主要区别是在方法上加了synchronized关键字。
相关推荐
适用人群:JavaSE初学者,对源码感兴趣的,想要深度了解ArrayList底层实现、数据结构、add方法、Remove方法、以及自动扩容机制的同学,并且对ArrayList已经有过使用,想要学习它与LinkedList,Vector等的区别,该...
ArrayList是Java编程语言中最常用的集合...总之,这个“ArrayList源码.zip”文件是Java程序员学习和优化代码的宝贵资源,它揭示了ArrayList内部的工作机制,帮助我们提升编程技巧,更好地理解和利用这个强大的集合类。
Java集合框架源码解读(1)——ArrayList、LinkedList和Vector Java集合框架源码解读(2)——HashMap Java集合框架源码解读(3)——LinkedHashMap Java集合框架源码解读(4)——WeakHashMap Java集合框架源码解读
在这个“java源码整理包-集合”中,包含了多种核心的集合类的源代码,如`List`、`Map`、`ArrayList`、`HashMap`、`HashSet`、`Hashtable`、`TreeMap`、`TreeSet`和`Vector`。这些源码对于深入理解Java集合的工作原理...
总结来说,这个"java模仿千千静听播放器源码"项目涵盖了Java Swing图形界面设计、Java Sound音频处理、数据结构与算法(如歌曲列表的管理)、多线程编程、资源管理(皮肤切换)以及面向对象设计等多个重要知识点。...
以上只是Java常用类的一部分,实际上还有很多其他重要的类,如`ArrayList`的同胞`Vector`,线程安全的`ConcurrentHashMap`,网络编程中的`Socket`和`ServerSocket`等。通过深入学习这些类的源码,不仅可以提高编程...
java面试 【作品名称】:最全的Java面试题、读书笔记、面试经验 【适用人群】:适用于希望学习不同... * [Vector源码剖析](Part2/JavaSE/Vector源码剖析.md) * [HashMap源码剖析](Part2/JavaSE/HashMap源码剖析.md)
"java-data-struct.rar_数据结构 java_数据结构源码"这个压缩包文件包含了用Java实现的数据结构的相关代码,对于学习和理解数据结构的实现具有很高的参考价值。 1. **链表(LinkedList)**:链表是一种线性数据结构...
学习笔记(持续更新中) 所有文章均同步发布到微信公众号【JavaRobot】,关注微信公众号,及时得到文章推送,谢谢支持。 说明:如无特别说明,所有代码都基于JDK8 JavaSE(Java基础) Java Core 关键字 synchronized...
在这个名为"javaarraylist源码-Data-Structures-Algorithms"的项目中,开发者分享了关于ArrayList和其他数据结构与算法的源代码实现,如Stack、LinkedList、Queue以及Binary Tree。 ArrayList的内部实现基于数组,...
通过对《Java并发编程艺术》源码的深入学习,你可以掌握上述知识点,并能够运用到实际项目中,编写出更加稳定和高效的并发程序。书中的例子和源码将有助于你理解和实践这些理论,从而提升你的并发编程能力。
4. 学习与调试:逐步阅读源码,理解每个类和方法的功能,通过调试工具观察程序运行过程,加深理解。 总之,这个AWT学生信息管理系统源码是一个很好的学习资源,它涵盖了Java GUI编程的基本概念和技术,同时也涉及到...
这份"Java数据结构学习资料源码.zip"包含了一系列与数据结构相关的学习资源,特别针对Java初学者,提供详细的代码案例,帮助他们从实践中理解这些基础概念。 首先,让我们探讨一下数据结构的基本概念。数据结构是...
总之,"java并发源码分析之实战编程"涵盖了许多关键知识点,从基本的线程操作到复杂的并发设计模式,都需要开发者深入学习和实践。通过研究源码,我们可以更深入地理解这些机制的工作原理,从而在实际开发中做出更优...
3. **栈**(Stack):栈是一种后进先出(LIFO)的数据结构,Java的`java.util.Stack`类是基于`Vector`实现的,支持常见的栈操作如`push`、`pop`、`peek`等。 4. **队列**(Queue):队列是一种先进先出(FIFO)的...
阅读这些源码可以帮助理解基础操作的实现,比如ArrayList和Vector的区别,通过阅读源码可以加深记忆。 进一步,可以研究core包中的String和StringBuffer,如果对Java IO有了解,可以尝试阅读FileReader等相关类。...
在这个项目中,开发者可能使用了Java的Canvas类来绘制游戏画面,用ArrayList或Vector来管理游戏对象,以及利用SerialObject或 RMS(Record Management System)进行数据存储。此外,游戏可能还包含网络功能,如排行...
这个系统提供了完整的源码、数据库以及相关的文档,对于学习Java GUI编程和数据库操作的学员来说,是一个非常实用的学习资源。 1. **Java Swing**: Java Swing是Java AWT(Abstract Window Toolkit)库的扩展,提供...
尽管`Vector`在Java集合框架中已经被`ArrayList`和`LinkedList`等更高效的类取代,但它的线程安全性使其在多线程编程的示例中仍然有用。不过,实际生产环境中的线程池实现往往会选择更高效的数据结构,例如`...