web-dev-qa-db-ja.com

java.lang.IndexOutOfBoundsException:ソースがdestに収まらない

次のコード:

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)

どうして?

63
andandandand

容量がサイズと等しくありません。渡すサイズパラメータは、サイズに十分なメモリを割り当てるだけです。実際には要素を定義しません。これは実際にはCollections.copyの愚かな要件ですが、それでも1つです。

Collections.copy JavaDocs のキー部分:

宛先リストは、少なくともソースリストと同じ長さでなければなりません。長い場合、宛先リスト内の残りの要素は影響を受けません。

ListArrayListのコンストラクターに渡して、すべてのListをコピーして、問題を完全に回避する必要があります。

78
pickypg

これは非常に良い質問であり、コレクション容量を設定しても必ずしも基礎となるオブジェクトが割り当てられるわけではないという事実と関係がありますが、次のことができるのになぜそうするのですか?

ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers);
18
paxdiablo

コンストラクターArrayList(Collection<? extends E> c)は、すべての要素をcから新しく作成されたインスタンスにコピーするため、numbersnumbersCopyにコピーします。これはnumbersCopy.addAll(numbers)と同じで、本当に必要なものです。

Collection.copyには、dest配列のすべての要素を保持するのに十分な大きさのsource配列が必要です。同様のアナロジーは、C関数memcpyなどです。

4
Yanick Rochon

Collections.copy()メソッドを使用して別のArrayListをコピーするためにArrayListを作成するとき、宛先Listに同じ数の値が含まれていることを確認する必要がありますソースListと同じサイズ。たとえば、ソースArrayListの値が[Red、Blue、Green]の場合、デスティネーションArrayListにも[Orange、Yellow、Blue]などの同じ数の要素が含まれている必要があります。ソースArrayListと同じサイズのArrayListを使用すると、OutOfBounds例外が発生します。

1
Arun Nair