ArrayListソースコードを深く分析する

3109 ワード

ArrayListというコンテナは実質的に自動的に成長する配列で、デフォルトの初期容量は10で、元のコンテナの1.5倍に拡張されています.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;

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param   initialCapacity   the initial capacity of the list
     * @exception IllegalArgumentException if the specified initial capacity
     *            is negative
     */
    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);
    }

無パラメータの構築方法は、デフォルトで容量のある構築方法が呼び出され、10に初期化されていることがわかります.つまり配列長が10のObjectタイプの配列であり,ここからもArrayListはオブジェクトのみを格納でき,生データを格納できないことが分かる.次に最も重要なコンテナにデータを追加する方法です.
/**
     * 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;
    }

/**
     * 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);
	}
    }
コンテナにデータを追加する方法では、要素を追加するたびにensure Capacity()メソッド、すなわちコンテナの長さを追加する方法が呼び出されることがわかります.ただし、伝達されるパラメータはsize+1であり、sizeはコンテナに含まれる要素の数である.したがって、毎回追加されるのは、要素の個数+1を含む値です.もちろんここでは判断がありますが、要素個数+1が元の配列長を超えると、拡張動作が実行されます.新しい配列の容量は元の配列の1.5倍になります.int newCapacity=(oldCapacity*3)/2+1で、配列コピーの動作が実行されます.つまりArrayListは自動的に長さが伸びる配列です.add()メソッドからもArrayListに重複する要素を追加することができ,要素が等しいか否かは判断されないことが分かる.