ArrayListの初期サイズ


257

次のようにして、ArrayListの初期サイズを設定できます。

ArrayList<Integer> arr=new ArrayList<Integer>(10);

しかし、あなたはできません

arr.add(5, 10);

範囲外の例外が発生するためです。

割り当てたスペースにアクセスできない場合の初期サイズの設定の用途は何ですか?

add関数は次のadd(int index, Object element)ように定義されているため、インデックス10に追加していません。


52
実際には、ドキュメントからの明らかでないリストは、少なくとも持っている必要があるとn個の項目がすることができます前に、追加set/add項目のn-1
認識

5
認識:明白かどうかはわかりませんが、明記されています。JavaDocを注意深く読む必要があります。スロー:IndexOutOfBoundsException-インデックスが範囲外の場合(index <0 || index> = size())。
Natix

3
うーん、コンストラクターは「指定された初期容量で空のリストを作成します。」と言い、空のリストの概念を採用すると、インデックス5は存在できません。しかし、これは一見見えないかもしれないことに同意します...
quaylar

12
また、配列を特定の値に初期化すると、その値よりも低いインデックスが使用可能であると想定することになりますArrayList。これはです。個人的には、特定の指標で入れられるようなサイズに設定できる方法が欲しいです。この方法は特にないようです。
アンドリューワイルド

1
コレクションをこのようにデザインしたのはどのNumbskullですか?これにより、可変長要素(つまり、各配列が異なる長さを持つことができるArrayList <String []>)を持つ構造体の並列インスタンス化に冗長な作業が強制されます。メモリがすでに割り当てられているため、N個の要素を追加した後にリストを再割り当てする必要がない場合、これらのインデックスには最初から直接アクセスできます。Oracleの誰も、C / C ++、C#、Objective C、Swiftの後にこのパターンを学んだことはありませんか?!
patrickjp93 2017年

回答:


387

配列リストのサイズとその容量を混同しています。

  • サイズは、リスト内の要素の数です。
  • 容量は、リストが潜在的にその内部構造を再割り当てすることなく対応することができますどのように多くの要素です。

を呼び出すとnew ArrayList<Integer>(10)、リストのサイズではなく、初期容量を設定します。言い換えると、この方法で構築された場合、配列リストは空の状態で始まります。

配列リストに10個の要素を追加する1つの方法は、ループを使用することです。

for (int i = 0; i < 10; i++) {
  arr.add(0);
}

これで、インデックス0..9の要素を変更できるようになりました。


51
+1:より短いループはwhile(arr.size() < 10) arr.add(0);、サイズが少なくともである必要があると言うことは便利かもしれません10。たとえば、次のように使用できますarr.set(9, n);
Peter Lawrey、2012年

10
+1:素晴らしい反応です。できれば+10をあげます。単一のコンストラクター呼び出しで初期サイズと初期容量の両方を設定できない理由は、APIからすぐにはわかりません。あなたは一種のapiを読んで、「ああ、ArrayListにはそれを行うためのメソッドまたはコンストラクターがないと思う」と言う必要があります
demongolem

@PeterLawreyコードは短くなる可能性がありますが、ループの反復ごとに1つではなく2つのメソッド呼び出しが含まれます。
ニューラルマー2018

@neuralmer実行時に実際のメソッド呼び出しが発生しないように、size()およびadd()がインライン化されることを期待します。
Peter Lawrey

109

事前に定義されたサイズのリストが必要な場合は、次も使用できます。

List<Integer> arr = Arrays.asList(new Integer[10]);

11
ここでは少し不利ですが、結果Listはnullでいっぱいです。Guavaを使用するInts.asList(new int[10])と、リストを0sで初期化できます。きれいなパターンですが、例をありがとう。
dimo414 2014

1
質問では、ArrayList <E>について話します。List <E>を使用しています。誰もこれを観察していませんか??? さらに、彼らはこの無関係な答えに賛成しています!私は絶対にしないので、私はあなたの答えに反対票を投じません。単に...ゴッド酒!
アポストロス2018

3
@Apostolos ArrayListListインターフェースの実装であり、をArrays.asList返しますArrayList。多形性を調べることをお勧めします。
リアムポッター

ただし、これは固定サイズのリストを返します。スローする要素を追加しようとしていますUnsupportedOperationException
Koray Tugay

47

Collections.fill(list、obj);を使用する場合。繰り返しオブジェクトでリストを埋めるために、代わりにあなたは使うことができます

ArrayList<Integer> arr=new ArrayList<Integer>(Collections.nCopies(10, 0));

この行は、ArrayListに0を10回コピーします。


20

の容量サイズArrayListと同じではありません。サイズは、(およびその他の実装)に含まれる要素の数と同じです。ArrayListList

容量は、内部的の要素を格納するために使用される基礎となる配列の長さだけでありArrayList、常に大きいかに等しいサイズのリストの。

set(index, element)リストを呼び出すときindex、はリスト要素の実際の数(=サイズ)(コードではゼロであるためAIOOBEスローされる)に関係し、配列の長さ(=容量)(実装の詳細に固有)には関係しませんへArrayList)。

このsetメソッドはList、などのすべての実装に共通ですLinkedList。これは実際には配列によって実装されず、リンクされたエントリのチェーンとして実装されます。

編集:実際にはadd(index, element)メソッドを使用しますset(index, element)が、ここでは原則は同じです。


10

インデックス付きの要素を追加する場合は、代わりに配列を使用できます。

    String [] test = new String[length];
    test[0] = "add";

5
OPは最初はリストを使用したいと思っていました...配列ではありません。
2016

9

10はALの初期容量であり、サイズ(0)ではありません。要素を追加するときに容量を拡張するオーバーヘッドを回避できるため、多くの要素を使用する場合は、初期容量を高い値に言及する必要があります。


6

あなたの質問に対する正確な答えは次のようになると思います:

ArrayListに初期サイズを設定すると、nrが減少します。内部メモリの再割り当てが発生する回数。リストは配列に支えられています。つまり、初期容量0を指定した場合、要素の最初の挿入時に、内部配列のサイズを変更する必要があります。リストが保持する要素数の概算がわかっている場合は、初期容量を設定するとnrが減少します。リストの使用中に発生するメモリの再割り当ての割合。


3

これは誰かを助けるかもしれません-

ArrayList<Integer> integerArrayList = new ArrayList<>(Arrays.asList(new Integer[10]));

3

これに遅れていますが、Java 8以降、私は個人的に、StreamAPIを使用したこの次のアプローチがより簡潔であり、受け入れられた回答の代わりになる可能性があると感じています。

例えば、

Arrays.stream(new int[size]).boxed().collect(Collectors.toList())

ここsizeで、は目的のListサイズであり、ここで説明した欠点がない場合、のすべての要素はとしListて初期化され0ます。

(私はクイック検索を行い、stream投稿された回答を何も見ませんでした-この回答が冗長であり、私がそれを削除できるかどうかを私に知らせてください)


1

現在、リストには要素がないため、リストのインデックス5が存在しない場合は追加できません。リストの容量を現在のサイズと混同しています。

ただ電話する:

arr.add(10)

IntegerをArrayListに追加するには


1

arraylistの容量は10ですが、実際のリストには要素がありません。addメソッドは、実際のリストに要素を挿入するために使用されます。要素がないため、インデックス5に要素を挿入できません。


1

10個のアイテムを追加したい場合は、次のようにしてみてくださいArrayList

for (int i = 0; i < 10; i++)
    arr.add(i);

すでに配列サイズ変数を宣言している場合はsize、数値「10」の代わりに変数を使用します


1

私は同様の問題に直面し、arrayListがListインターフェイスのサイズ変更可能な配列の実装であることを知っているだけでなく、任意のポイントに要素を追加できることを期待していますが、少なくとも初期サイズを定義するオプションがあります。とにかく、最初に配列を作成し、それを次のようなリストに変換できます。

  int index = 5;
  int size = 10;

  Integer[] array = new Integer[size];
  array[index] = value;
  ...
  List<Integer> list = Arrays.asList(array);

または

  List<Integer> list = Arrays.asList(new Integer[size]);
  list.set(index, value);

0

ArrayList myList = new ArrayList(10);

//  myList.add(3, "DDD");
//  myList.add(9, "III");
    myList.add(0, "AAA");
    myList.add(1, "BBB");

    for(String item:myList){
        System.out.println("inside list : "+item);
    }

/ * arraylistの初期容量を宣言することは、内部でシフト時間を節約することに他なりません。要素を内部で追加する場合、容量をチェックして容量を増やします。最初に0インデックスで要素を追加し、その後1で追加します。* /


0

私の2セントStream。使う方がいいと思います

IntStream.generate(i -> MyClass.contruct())
         .limit(INT_SIZE)
         .collect(Collectors.toList());

初期値を設定できる柔軟性を備えています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.