在编程中经常会使用到集合,而集合中最常用的是ArrayList。
集合中存放的依然是对象的引用,而不是对象本身,和数组一样。
当我们学习了数组又学习集合时,发现集合很神奇。数组需要在定义的时候声明大小,而ArrayList不用管大小,定义了以后可以随便使用。
查看ArrayList的源代码,可以发现,ArrayList底层是用数组进行存放元素的。ArrayList并不神奇,底层实现是通过一个对象数组Object[]来存放元素,由于是对象数组,所以只能存放对象,并可以存放任何对象。而数组存放了对象的引用,所以ArrayList也存放对象的引用。
ArrayList的两个构造函数:
我们通常使用ArrayList时会使用其不带参数的构造函数,或指定一个容量的参数的构造函数,而其底层实现是不带参数的构造函数会调用带参数的构造函数,只是不带参数的构造函数会默认使用传递一个10参数,带参数的构造函数中会声明一个长度为10的Object数组。
/**
* 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;
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
this.elementData = new Object[initialCapacity];
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this(10);
}下面是我们经常使用的add方法,该方法首先会判断底层数组的长度是否大于需要的长度,让将元素放入底层数组中。
/**
* 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) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}ArrayList的size()方法返回的是集合的大小,其实是底层数组的长度。
ArraList中一个很重要的方法(ArrayList底层是使用数组实现的,为什么它可以无限添加元素呢?)
下面这个方法ensureCapacity做了实现,minCapacity是要追加元素的位置,它和底层数组的大小做比较,如果小于底层数组的长度则什么也不做;重点在大于底层数组长度时,它做了一些事情:将原数组的大小进行扩容,扩多大呢,原数组的3/2+1;然后使用Arrays.copyOf方法,将原数组的元素拷贝到新指定大小的数组里,至此实现数组的扩容。
/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
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);
}
}原文地址:http://zlfwmm.blog.51cto.com/5892198/1707006