容量はあなたが説明したとおりです-値の保存のためにArrayListに割り当てられた連続したメモリ。ArrayList はすべての値を配列に格納し、配列のサイズを自動的に変更します。これにより、サイズ変更時にメモリ管理のオーバーヘッドが発生します。
私の記憶が正しければ、Java は ArrayList のバッキング配列のサイズをサイズ N からサイズ 2N + 2 に増やします。これは、容量を超える要素を 1 つ追加しようとするとです。insert
メソッド (または同様の方法) を使用して、容量の終わりを超えて特定の位置に挿入すると、どのサイズまで増加するか、またはこれが許可されるかどうかさえわかりません。
これがどのように機能するかを考えるのに役立つ例を次に示します。s の間の各スペースを|
バッキング配列のセルとして描写します。
| | |
サイズ = 0 (要素を含まない)、容量 = 2 (2 つの要素を含むことができる)。
|1| |
サイズ = 1 (要素を 1 つ含む)、容量 = 2 (要素を 2 つ含むことができる)。
|1|2|
サイズ = 2、容量 = 2。別の要素を追加:
|1|2|3| | | |
サイズが 1 増加し、容量が 6 (2 * 2 + 2) に増加しました。JVM は適切な場所を検索する必要があるため、大きな連続したメモリ領域を割り当てるには少し作業が必要になる可能性があるため (多くの小さなメモリ断片を割り当てる LinkedList とは対照的に)、大きな配列ではコストがかかる可能性があります。 OSにメモリの追加を要求します。また、大量の値をある場所から別の場所にコピーすることもコストがかかります。これは、そのような領域が見つかった場合に行われます。
私の経験則は次のとおりです。必要な容量がわかっている場合は、ArrayList を使用します。これは、割り当てが 1 つしかなく、アクセスが非常に高速であるためです。必要な容量がわからない場合は、LinkedList を使用してください。新しい値を追加するのに必要な作業量は常に同じであり、コピーは必要ありません。