このコードがIndexOfOutBoundsExceptionをスローする理由-別名、ensureCapacity()の問題
質問
次の2つのコードスニペットを検討してください。
int index = 676;
List<String> strings = new ArrayList<String>();
strings.add(index, "foo");
and
int index = 676;
List<String> strings = new ArrayList<String>();
strings.ensureCapacity(index);
strings.add(index, "foo");
最初のケースでは、IndexOfOutBoundsExceptionが表示されても驚くことではありません。 API 、add(int index, E element)
は、インデックスが(index < 0 || index > size())
<!> quot;の範囲外の場合、IndexOfOutBoundsException <!> quot;をスローします。 strings
のサイズは要素が追加される前は0であるため、インデックスは間違いなくArrayListのサイズより大きくなります。
ただし、2番目のケースでは、ensureCapacity
の呼び出しがインデックス676に文字列add
を正しく挿入するように"foo"
の呼び出しがadd(index, "foo")
に成長することを期待しますが、そうではありません。
-
なぜいけないのですか
-
index > strings.size()
が<=>で機能するようにするにはどうすればよいですか?
解決
ArrayListの基になる配列の容量は、上位レベルのList APIメソッド(追加、削除など)とは異なり、バッキング配列のサイズのみを表します。リストの境界を超えて要素を追加できるようにしたい場合は、ユーティリティクラスに自分でコードを作成する(または、それを行うコレクションを見つける)必要があります。null、空のオブジェクト、またはインデックスと古いサイズ。
他のヒント
ArrayList.ensureCapacity()は、(size()によって返される)リストの実際のサイズを変更しませんが、このサイズに成長するためにバッファを再割り当てする必要がないように、内部バッファを再割り当てしますlist.add(object)を呼び出します。
/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*/
思い切って推測すると、あなたが探しているのは
Integer index = Integer.valueOf(676);
Map<Integer,String> strings = new HashMap<Integer,String>();
strings.put(index, "foo");
長さは676ですが、ゼロベースであることを覚えておく必要があるため、実際には、インデックス-1が最大数になります。