の容量を見つける方法はArrayList
?
8 に答える
私は興味があります、あなたはそれを何のために必要としますか?容量は(聞こえるかもしれませんが)ArrayListに入れることができる量の上限ではないことを知っておく必要があります。これは、内部配列を強制的に再割り当てせずに、リストに入れることができるデータの量を表す値です。基本的に、容量の概念は、パフォーマンスをわずかに微調整するためにのみ存在します。
とにかく、おそらくあなたはすでにそれを知っているので、ここに実際の答えがあります。
ArrayList用のAPIによって提供されるインターフェースは、そのようなユースケースを単にサポートしていません。これには多くの理由があります。理由の1つは、これを気にする必要がないということです。ArrayListは、容量などの詳細から抽象化する無制限の配列と見なす必要があります。
容量の制御に最も近いのは、コンストラクターArrayList(int initialCapacity)
、および2つのメソッドtrimToSize()
とensureCapacity(int minCapacity)
です。
しかし、楽しみのために、私は醜いリフレクションハック(これを使用しないでください)を通してそれを解決することができました:
import java.lang.reflect.Field;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) throws Exception {
ArrayList<Integer> list = new ArrayList<Integer>(3);
for (int i = 0; i < 17; i++) {
list.add(i);
System.out.format("Size: %2d, Capacity: %2d%n",
list.size(), getCapacity(list));
}
}
static int getCapacity(ArrayList<?> l) throws Exception {
Field dataField = ArrayList.class.getDeclaredField("elementData");
dataField.setAccessible(true);
return ((Object[]) dataField.get(l)).length;
}
}
出力:
Size: 1, Capacity: 3
Size: 2, Capacity: 3
Size: 3, Capacity: 3
Size: 4, Capacity: 5
Size: 5, Capacity: 5
Size: 6, Capacity: 8
Size: 7, Capacity: 8
Size: 8, Capacity: 8
Size: 9, Capacity: 13
Size: 10, Capacity: 13
Size: 11, Capacity: 13
Size: 12, Capacity: 13
Size: 13, Capacity: 13
Size: 14, Capacity: 20
Size: 15, Capacity: 20
Size: 16, Capacity: 20
Size: 17, Capacity: 20
いいえ、あなたがすることはできません !Java ArrayListは、現在の容量にアクセスする方法を提供しません。
コンストラクターArrayList(int initialCapacity)を使用して初期容量を指定するArrayListを作成するか、ensureCapacity ()を呼び出して容量を増やすことしかできません。
これArrayList
は、自動的に拡張可能な要素の抽象化です。List
その容量を知る必要はめったにありません。効果的なJava2ndEdition、アイテム52を検討してください:インターフェースでオブジェクトを参照してください。ArrayList
実用的である限り、それがanであるかLinkedList
;であるかを気にする必要はありません。それはただのList
です。
そうは言っても、これらの方法はあなたにとって興味深いかもしれません:
ArrayList(int initialCapacity)
- 指定された初期容量で空のリストを作成します。
void ensureCapacity(int minCapacity)
ArrayList
必要に応じて、このインスタンスの容量を増やして、少なくとも最小容量引数で指定された数の要素を保持できるようにします。
void trimToSize()
- この
ArrayList
インスタンスの容量をリストの現在のサイズにトリミングします。アプリケーションはこの操作を使用して、ArrayList
インスタンスのストレージを最小限に抑えることができます。
- この
APIはそれを提供しません。内部的には、容量がフルのときにadd(..)が呼び出されると、容量は係数で乗算されます。ただし、Java仕様では、この定数係数については何も述べられていません... Sunの実装では1.5の係数を使用するため、容量の上限は1.5 * size()になります。
TrimToSize()を使用してリストを「圧縮」し、容量をsize()と等しくすることができることを忘れないでください。
仕様から: 「容量は、リスト内の要素を格納するために使用される配列のサイズです。これは常に、少なくともリスト サイズと同じ大きさです。要素が ArrayList に追加されると、その容量は自動的に大きくなります。詳細については、要素の追加には一定の償却時間コストがあるという事実を超えて、成長ポリシーは指定されていません。」
そのため、現在の容量がどの程度か、またどのように増加するかを知る方法はありません。
私はここでトレンドに逆らうつもりです...ユーザーは、コンテキストがなくても質問をしています。コンテキストがなければ、バッキング アレイが対応するために拡張されるため、容量を知る必要はありません...
次のようにして、ArrayList の容量を確実に知ることができます。副次的効果は、バッキング配列が配列内の要素の正確な数にトリムされることです:
ArrayList list = new ArrayList();
//add a bunch of elements
list.trimToSize();
System.out.println("Capacity = " + list.size());
楽しみ!
容量について心配する必要はありません。これは内部実装の詳細です。内部配列がいっぱいになると、拡張されます。メソッドを使用して、現在 ArrayList に含まれている要素の数を確認できますsize()
。
これは実行時に必要ですか、それともテストの実行中に取得しても問題ありませんか? そのテストの場合、通常、お気に入りの IDE デバッガーを使用して容量を確認できます。正確な数値はわかりませんが、通常は 1.7 が容量の増加サイズです。したがって、10 個の項目を持つ arraylist を作成すると、Java はサイズを 17 にします。