ArrayList
のパラメータ(int initialCapacity)
の意味は、要素の数だと思いましたが、これを実行すると機能しませんでした。
public class MyClass {
private ArrayList<Integer> arr;
public MyClass(int n_elements) {
arr = new ArrayList<Integer>(n_elements);
}
}
これは初期容量です。つまり、ArrayList
がアイテムの内部ストレージとして最初に割り当てるアイテムの数です。
ArrayList
には「任意の数のアイテム」を含めることができ(メモリがある限り)、大きな初期挿入を行う場合は、ArrayList
に最初に大きなストレージを割り当てるように指示できます。次のアイテムにより多くのスペースを割り当てようとすると、CPUサイクルが無駄になります。
例:
ArrayList list = new ArrayList<Integer>(2);
list.add(1); // size() == 1
list.add(2); // size() == 2, list is "filled"
list.add(3); // size() == 3, list is expanded to make room for the third element
実際には、バックグラウンドでサイズを変更する前にArrayList
に追加できる要素の数です。これにより、正しく使用すれば、いくつかのサイクルを節約できます。
容量は、オブジェクトの内部ストレージのサイズです。内部ストレージは常にリストのsize()以上です(すべての要素を含めることができるようにするため)。
public class Main {
public static void main(String[] args) throws Exception {
ArrayList<Integer> arr = new ArrayList<>();
System.out.println("initial size = " + arr.size()); // 0
System.out.println("initial capacity = " + getCapacity(arr));
for (int i = 0; i < 11; i++)
arr.add(i);
System.out.println("size = " + arr.size()); // 11
System.out.println("capacity = " + getCapacity(arr));
}
static int getCapacity(ArrayList<?> l) throws Exception {
Field dataField = ArrayList.class.getDeclaredField("elementData");
dataField.setAccessible(true);
return ((Object[]) dataField.get(l)).length;
}
}
これを実行すると、次のようになります。
initial size = 0
initial capacity = 10
size = 11
capacity = 16
内部的には、ArrayList
は本質的に 動的配列 です。 new Arraylist<>()
を使用してインスタンス化するたびに、格納する値を保持する配列が作成されます。そのデフォルトの容量 サイズと混同しないでください は10です。
容量を超えてサイズを増やす値を追加するたびに、前の配列の内容がコピーされた前の容量の150%を超える容量の新しい配列が作成されます。
結果のリストのサイズについて一般的な考えがある場合、または確実であるが、配列に対して配列リストを使用することで得られる柔軟性が必要な場合は、新しい配列を作成し、古い配列の内容をコピーするこの繰り返しプロセスを防ぐための容量を設定できます。新しいものを削除し、古いものを削除します。そうしないと、リストのサイズに比例して出現回数が増加します。