java.lang.IndexOutOfBoundsException: Quelle passt nicht in Ziel

Lesezeit: 4 Minuten

Benutzer-Avatar
undundundund

Auf den folgenden Code:

static void findSubsets (ArrayList<Integer> numbers, int amount, int index)
{
    ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers.size());
    Collections.copy(numbersCopy, numbers);
}

Ich bekomme den Fehler:

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)

Wieso den?

Kapazität ist nicht gleich Größe. Der Größenparameter, den Sie übergeben, weist einfach genügend Speicher für die Größe zu. Es definiert nicht wirklich Elemente. Es ist eigentlich eine Art dumme Anforderung von Collections.copyaber es ist trotzdem eine.

Der Schlüsselteil aus der Collections.copy JavaDocs:

Die Zielliste muss mindestens so lang sein wie die Quellliste. Wenn es länger ist, bleiben die restlichen Elemente in der Zielliste unberührt.

Sie sollten einfach passieren List zum ArrayList‘s-Konstruktor, um alle zu kopieren List um das Problem ganz zu vermeiden.

  • Ich habe dies heruntergestuft, weil das Hinzufügen zum Konstruktor a [b]seicht[/b] kopieren und ist nicht dasselbe wie eine tiefe Kopie. Wenn Sie die Elemente in der ursprünglichen Liste manipulieren, werden sie auch in der ‘kopiert nach’-Liste manipuliert

    – Junge

    29. November 2014 um 13:12 Uhr

  • @Boy Dein Punkt ist falsch. Siehe die Quellcode für ArrayList wo eine tiefe Kopie der Liste erfolgt über einen Anruf bei toArray und Arrays.copyOf. Änderungen, die an einer der Listen vorgenommen wurden, nachdem numbersCopy = new ArrayList<Integer>(numbers) tut nicht das andere bewirken. Das würde sicherlich den Zweck des Konstruktors zunichte machen (und es braucht a Collection und nicht ein List ohnehin).

    – wählerisch

    1. Dezember 2014 um 2:07 Uhr

  • @Boy Es sei denn, Sie kommen auf die Tatsache, dass die Elemente selbst werden nicht auch für eine echte tiefe Kopie rekonstruiert? Da Java keine Kopierkonstruktoren benötigt, wäre dies eine nahezu unmögliche Anforderung und eine solche Collections.copy tritt auch nicht auf.

    – wählerisch

    1. Dezember 2014 um 2:10 Uhr

  • Ich wusste nicht, dass das „Neue“ sich nicht auf die Liste des anderen auswirkt. Entschuldigung, dass ich falsch liege…

    – Junge

    1. Dezember 2014 um 10:48 Uhr

  • Eine tiefe Kopie ist besser definiert als “jede Änderung an irgendeinem Teil des neuen Objekts hat keine Auswirkung auf das alte Objekt”, daher ist eine tiefe Kopie von “nur dem Listenbit” nicht wirklich sinnvoll. Wären Teile des ursprünglichen Objekts veränderbar, könnten sich das neue und das alte Objekt gegenseitig beeinflussen, sodass es sich nicht um eine tiefe Kopie handeln würde. Bei unveränderlichen Elementen in der Liste (wie z Integer in dieser Frage), gibt es keinen Funktionsunterschied zwischen einer flachen und einer tiefen Kopie.

    – paxdiablo

    25. Juli 2020 um 1:35 Uhr


Benutzer-Avatar
paxdiablo

Das ist eine sehr gute Frage und hat mit ziemlicher Sicherheit damit zu tun, dass das Festlegen einer Sammlungskapazität nicht unbedingt die zugrunde liegenden Objekte zuweist, aber warum tun Sie es so, wenn Sie es einfach können:

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

  • es kopiert Referenz

    – Temirbek

    20. Juli 2017 um 11:55 Uhr

  • @temirbek, nein wird es nicht. Ich habe es gerade plus Quellcode getestet (hg.openjdk.java.net/jdk7/modules/jdk/file/a37326fa7f95/src/…) sagt Arrays.copyOf() bedeutet, dass es sich um eine nicht referenzierte Kopie handelt

    – Farid

    5. Oktober 2019 um 13:37 Uhr


  • @ Snedden27: ja, oberflächlich, aber in diesem Fall spielt es keine Rolle, da Integer ist unveränderlich.

    – paxdiablo

    25. Juli 2020 um 1:29 Uhr

Der Konstrukteur ArrayList(Collection<? extends E> c) kopiert alle Elemente aus c in die neu erstellte Instanz einfügen und damit kopieren numbers hinein numbersCopy. Es ist dasselbe wie numbersCopy.addAll(numbers) auch, was Sie wirklich brauchen.

Sinn macht das schon Collection.copy erfordert die dest Das Array muss groß genug sein, um alle Elemente aus dem aufzunehmen source Reihe. Eine ähnliche Analogie ist die C-Funktion memcpy und dergleichen.

Benutzer-Avatar
Arun Nair

Beim Erstellen einer ArrayList einen anderen zu kopieren ArrayList verwenden Collections.copy() Methode müssen wir sicherstellen, dass das Ziel List enthält die gleiche Anzahl von Werten (nicht nur die gleiche Größe) wie die Quelle List. Zum Beispiel, wenn Quelle ArrayList Werte hat [Red,Blue,Green]dann das Ziel ArrayList sollte auch die gleiche Anzahl von Elementen wie enthalten [Orange,Yellow,Blue].Wenn wir eine erstellen ArrayList mit der gleichen Größe wie die Quelle ArrayListwird es geben OutOfBounds Ausnahme.

Sie können auch Collections.addAll verwenden, wie Angenommen, wir müssen dann List1 nach List2 kopieren
List2.addAll(List1);
Hier werden die Dateien hinzugefügt, wenn Sie es effizienter wollen, dann stellen Sie sicher, dass Sie die Liste2 löschen, bevor Sie die Elemente von Liste1 hinzufügen, wie hier,
list2.clear();

Benutzer-Avatar
Ahmad Al-Kurdi

Unter java8+

List<Integer> numbersCopy = numbers.stream().collect(Collectors.toList());

Es ist einfacher in Java 10+

List<Integer> numbersCopy = List.copyOf(numbers);

Aufführen.copyOf() gibt ein zurück unmodifiable Liste mit den Elementen der angegebenen Collection.

1216170cookie-checkjava.lang.IndexOutOfBoundsException: Quelle passt nicht in Ziel

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy