次のコード:
static void findSubsets (ArrayList<Integer> numbers, int amount, int index)
{
ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers.size());
Collections.copy(numbersCopy, numbers);
}
エラーが発生しています:
Exception in thread "main" Java.lang.IndexOutOfBoundsException: Source does not fit in dest
at Java.util.Collections.copy(Collections.Java:548)
at backtracking2.Main.findSubsets(Main.Java:61)
どうして?
容量がサイズと等しくありません。渡すサイズパラメータは、サイズに十分なメモリを割り当てるだけです。実際には要素を定義しません。これは実際にはCollections.copy
の愚かな要件ですが、それでも1つです。
Collections.copy
JavaDocs のキー部分:
宛先リストは、少なくともソースリストと同じ長さでなければなりません。長い場合、宛先リスト内の残りの要素は影響を受けません。
List
をArrayList
のコンストラクターに渡して、すべてのList
をコピーして、問題を完全に回避する必要があります。
これは非常に良い質問であり、コレクション容量を設定しても必ずしも基礎となるオブジェクトが割り当てられるわけではないという事実と関係がありますが、次のことができるのになぜそうするのですか?
ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers);
コンストラクターArrayList(Collection<? extends E> c)
は、すべての要素をc
から新しく作成されたインスタンスにコピーするため、numbers
をnumbersCopy
にコピーします。これはnumbersCopy.addAll(numbers)
と同じで、本当に必要なものです。
Collection.copy
には、dest
配列のすべての要素を保持するのに十分な大きさのsource
配列が必要です。同様のアナロジーは、C関数memcpy
などです。
Collections.copy()
メソッドを使用して別のArrayList
をコピーするためにArrayList
を作成するとき、宛先List
に同じ数の値が含まれていることを確認する必要がありますソースList
と同じサイズ。たとえば、ソースArrayList
の値が[Red、Blue、Green]の場合、デスティネーションArrayList
にも[Orange、Yellow、Blue]などの同じ数の要素が含まれている必要があります。ソースArrayList
と同じサイズのArrayList
を使用すると、OutOfBounds
例外が発生します。