jdk源码剖析之ArrayList
来源:互联网 发布:杰拉德华莱士数据 编辑:程序博客网 时间:2024/05/01 17:46
ArrayList中最重要的是elementData数组和size,主要是通过数组实现。ArrayList中有几点细节需要了解:
1.创建对象时分配的空间。
ArrayList的构造方法中并没有为elementData数组分配空间,而是在Add方法中判断当前ArrayList是否为空,若为空则分配DEFAULT_CAPACITY(10)的空间。
/** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; } /** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
2.ArrayList数组空间分配的原则,数组大小增长的规律
ArrayList中grow方法说明了数组大小的分配,当我们数组大小需要扩容的时候是通过扩大到原来的1.5倍来解决,若扩大到1.5倍无法解决问题,则直接扩大到我们需要的minCapacity,最后若minCapacity比我们配置的MAX_ARRAY_SIZE还要大,则扩展到Integer.MAX_VALUE。因此我们可以看出ArrayList支持的最大为Integer.MAX_VALUE,否则就会抛出OutOfMemoryError。
/** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }3.elementData为何定义为transient?
这是为了序列化是不序列化elementData,由于在elementData中有许多分配的空的空间,若进行序列化会造成空间的浪费。在序列化与反序列化过程中会调用writeObject和readObject方法,只会存有有效的信息。
/** * 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 size as capacity for behavioural compatibility with clone() s.writeInt(size); // 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 { elementData = EMPTY_ELEMENTDATA; // Read in size, and any hidden stuff s.defaultReadObject(); // Read in capacity s.readInt(); // ignored if (size > 0) { // be like clone(), allocate array based upon size not capacity ensureCapacityInternal(size); Object[] a = elementData; // Read in all elements in the proper order. for (int i=0; i<size; i++) { a[i] = s.readObject(); } } }
4.ArrayList的应用场景
其应用场景其实就是数组的应用场景,适用于读多写少的场景,因为对于数组的读相对简单,依赖索引的读,其时间复杂度为O(1),但是数组依赖索引的写时间复杂度为O(n)。
0 0
- jdk源码剖析之ArrayList
- Java源码剖析之ArrayList
- JDK源码学习之ArrayList
- JDK源码阅读之ArrayList
- JDK源码解析之ArrayList
- jdk集合源码之ArrayList
- jdk源码分析之ArrayList
- JDK之ArrayList源码解析
- JDK之ArrayList源码解读
- JDK源码解析之ArrayList
- JDK源码走读之ArrayList
- jdk源码阅读之ArrayList
- jdk源码剖析之EnumMap
- jdk源码剖析之LinkedList
- 【源码解析】JDK源码之ArrayList
- 深入集合框架之ArrayList源码剖析
- JDK源码剖析与最佳实践—ArrayList
- 【源码】ArrayList源码剖析
- lintcode(371)用递归打印数字
- PAT1029 旧键盘
- inner join on, left join on, right join on详细使用方法
- 使用谷歌翻译pdf内容小技巧——快速替换换行
- 同步 异步 回调
- jdk源码剖析之ArrayList
- 开源 java CMS
- 深度学习tensorflow安装ubuntu16.04amd64
- win7 QT 安装 + 使用
- Python开发简单爬虫
- 经典面试题:HTTP协议理解
- 关于mssql中精确精准的字段类型推荐使用numeric
- Rest服务开发指南—常用注解说明
- Libpcap编程(5)理论总结