ArrayList做为List接口的可变数组的实现,我觉得很有必要去看下源代码,看看N人是怎么实现有序集合的。
首先,看下add方法的实现,看看它是如何实现数组长度可变的。源码如下:
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
对于返回的值永远为true这个现象,我们暂且搁置不理,看下方法中的第二句代码,很容易理解,可以看下elementData数组变量是如何申明的。源码如下:
private transient Object[] elementData;
代码中出现了一个我看不太明白的关键字transient,得去查查这个关键字是什么意思。
transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
原来是一个用来标志是否串行化的关键字,貌似我现在还用不上,飞过。
光查看elementData的申明肯定不行,得去看下它是如何初始化的,如何new出来的。源码如下:
public ArrayList() { this(10); } public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } public ArrayList(Collection c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); }一下子就把ArrayList的三个构造方法全部列出来了,很突然,也很有必要。
首先,我们看下无参的构造方法,相当的easy,跳过。看下参数为int的构造方法,突然发现也非常简单。略微提一下,当你使用ArrayList new对象时,最好不要传入小于0的整数。
很显然,第三个构造方法才是重点。从这里,我们会发现,Collection的toArray方法是那么的重要。看到了这一点就可以了。我们回到刚开始的add方法。列出ensureCapacityInternal方法的实现。
private void ensureCapacityInternal(int minCapacity) { modCount++;//shut,怎么又来一个我不清楚底细的变量?! // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }很突然的,我发现我漏掉了几个重要的类没有看,他们就是AbstractList,AbstractCollection,赶紧去看看。