Java ArayList拡張問題の実例を詳しく説明する。


本論文で研究したのは主にJava ArayList拡張問題の実例について詳しく解説した関連内容であり、具体的には以下の通りである。
まず、ArayListの中身はObjectタイプの配列であり、ArayListの拡大問題は実はこのObjectタイプの配列拡大問題であることを知る必要があります。

transient Object[] elementData; 
一、作成時、ArayListの容量割り当て
ArayListを作成するには3つの状況があります。
1、標準サイズの作成(デフォルトは0)

ArrayList al = new ArrayList();
作成が完了したら、alの容量は0です。下のコードから分かります。

transient Object[] elementData; 
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

public ArrayList() {
  this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
2、指定サイズの作成

ArrayList al = new ArrayList(5);
容量5のArayListオブジェクトを作成します。つまり長さ5のObject配列です。下のコードから分かります。

transient Object[] elementData; 
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

public ArrayList(int initialCapacity) {
  if (initialCapacity > 0) {
    this.elementData = new Object[initialCapacity];
  } else if (initialCapacity == 0) {
    this.elementData = EMPTY_ELEMENTDATA;
  } else {
    throw new IllegalArgumentException("Illegal Capacity: "+
                      initialCapacity);
  }
}
3、指定要素セットの作成

ArrayList al = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
上にArayListオブジェクトが作成され、1つのListが[1,2,3,4,5]で初期化されます。つまり、長さ5のObject配列を作成しました。配列の内容は[1,2,3,4,5]です。下のコードから分かります。

private int size;
transient Object[] elementData; 
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

public ArrayList(Collection<? extends E> c) {
  elementData = c.toArray();
  if ((size = elementData.length) != 0) {
    // c.toArray might (incorrectly) not return Object[] (see 6260652)
    if (elementData.getClass() != Object[].class)
      elementData = Arrays.copyOf(elementData, size, Object[].class);
  } else {
    // replace with empty array.
    this.elementData = EMPTY_ELEMENTDATA;
  }
}
二、要素を挿入する場合、ArayListの容量が拡張される。

ArrayList<Integer> collection = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
Integer[] moreInts = { 6, 7, 8, 9, 10 };
collection.addAll(Arrays.asList(moreInts));
上記の過程は以下の通りです。
1、sizeは5のArayListを作成します。内容は[1,2,3,4,5]です。初期容量は5です
2、このArayListオブジェクトに集合{6、7、8、9、10}を追加します。―――このときは、このアラーリストオブジェクトの容量を拡充する必要があります。
ソースの表示:

public Boolean addAll(Collection<? extends E> c) {
	//       
	Object[] a = c.toArray();
	//         
	int numNew = a.length;
	ensureCapacityInternal(size + numNew);
	// Increments modCount
	System.arraycopy(a, 0, elementData, size, numNew);
	size += numNew;
	return numNew != 0;
}
private void ensureCapacityInternal(int minCapacity) {
	//  ArrayList       
	if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
		minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
	}
	ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
	modCount++;
	//            minCapacity
	if (minCapacity - elementData.length > 0)
	    grow(minCapacity);
}
private void grow(int minCapacity) {
	// ArrayList     
	int oldCapacity = elementData.length;
	//                  ,            1.5 
	int newCapacity = oldCapacity + (oldCapacity >> 1);
	//           minCapacity  ,            
	if (newCapacity - minCapacity < 0)
	    newCapacity = minCapacity;
	//              
	if (newCapacity - MAX_ARRAY_SIZE > 0)
	    newCapacity = hugeCapacity(minCapacity);
	//   
	elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
	// minCapacity  0,    ,               
	if (minCapacity < 0) // overflow
	throw new OutOfMemoryError();
	return (minCapacity > MAX_ARRAY_SIZE) ?
	    Integer.MAX_VALUE :
	    MAX_ARRAY_SIZE;
}
上記の過程はこのようにまとめられます。
1、アラーリストのオリジナルサイズsize+をセットに挿入するサイズnumNew=拡充後のアラーリストの最小長さはminCapacityです。
2、もしArayListのオリジナルサイズsizeが0であれば、つまりArayListが空であり、ArayList拡充後の最小長さはminCapacity=Math.max(10、minCapacity)、つまり拡充後の最小長さはminCapacityであり、元の長さsizeに加えて集合の長さnumwを挿入するだけではない。
3、上で得られた拡充後の最小長さはminCapacityで、最終拡充後の長さではなく、さらに計算する必要があります。
(1)ArayListのオリジナルサイズのoldCapacityを得る
(2)新規拡充後のサイズ:newCapacity=oldCapacity*1.5;
(3)上で計算した拡充後の最小長さのminCapacityをここで得られた拡充後のサイズnewCapacityと比較し、大きいサイズのものを取って最終拡充後の大きさとする。
締め括りをつける
以上が本論文のArayList拡張問題の実例について詳しく説明した内容の全部です。興味のある方は引き続き当駅の他のテーマを参照してください。友達のサポートに感謝します。