Java IndexOutOfBoundsException "Bron past niet in bestemming"

1. Overzicht

In Java een kopie maken van een Lijst kan soms een IndexOutOfBoundsException: "Bron past niet in bestemming". In deze korte tutorial gaan we kijken waarom we deze foutmelding krijgen bij het gebruik van de Collections.copy methode en hoe deze kan worden opgelost. We zullen ook kijken naar alternatieven voor Collections.copy om een ​​kopie van de lijst te maken.

2. Reproductie van het probleem

Laten we beginnen met een methode om een ​​kopie van een Lijst de ... gebruiken Collections.copy methode:

statische lijst copyList (lijstbron) {lijstbestemming = nieuwe ArrayList (source.size ()); Collections.copy (bestemming, bron); terugkeerbestemming; }

Hier de copyList method maakt een nieuwe lijst aan met een initiële capaciteit die gelijk is aan de grootte van de bronlijst. Vervolgens probeert het de elementen van de bronlijst naar de bestemmingslijst te kopiëren:

Lijstbron = Arrays.asList (1, 2, 3, 4, 5); Lijst kopiëren = copyList (bron);

Zodra we echter het copyList methode, genereert het een uitzondering java.lang.IndexOutOfBoundsException: bron past niet in dest.

3. Oorzaak van de Uitzondering

Laten we proberen te begrijpen wat er mis is gegaan. Volgens de documentatie voor het Collections.copy methode:

De bestemmingslijst moet minstens zo lang zijn als de bronlijst. Als het langer is, worden de resterende elementen in de bestemmingslijst niet beïnvloed.

In ons voorbeeld hebben we een nieuw Lijst een constructor gebruiken met een initiële capaciteit die gelijk is aan de grootte van de bronlijst. Het wijst eenvoudig genoeg geheugen toe en definieert eigenlijk geen elementen. De grootte van de nieuwe lijst blijft nul omdat de capaciteit en de grootte verschillende attributen zijn van de Lijst.

Daarom, wanneer de Collections.copy methode probeert de bronlijst naar de bestemmingslijst te kopiëren, het gooit java.lang.IndexOutOfBoundsException.

4. Oplossingen

4.1. Collections.copy

Laten we naar een werkend voorbeeld kijken om een Lijst naar een ander Lijst, de ... gebruiken Collections.copy methode:

Lijstbestemming = Arrays.asList (1, 2, 3, 4, 5); Lijstbron = Arrays.asList (11, 22, 33); Collections.copy (bestemming, bron);

In dit geval kopiëren we alle drie de elementen van de bronlijst naar de bestemmingslijst. De Arrays.asList methode initialiseert de lijst met elementen en niet alleen een grootte, daarom kunnen we de bronlijst met succes naar de bestemmingslijst kopiëren.

Als we gewoon de argumenten van de Collections.copy methode, het zal gooien java.lang.IndexOutOfBoundsException omdat de grootte van de bronlijst kleiner is dan de grootte van de bestemmingslijst.

Na deze kopieerbewerking ziet de bestemmingslijst er als volgt uit:

[11, 22, 33, 4, 5]

Samen met de Collections.copy methode, zijn er andere manieren in Java om een ​​kopie van te maken Lijst. Laten we er een paar bekijken.

4.2. ArrayList Constructor

De eenvoudigste manier om een Lijst gebruikt een constructor die een Verzameling parameter:

Lijstbron = Arrays.asList (11, 22, 33); Lijstbestemming = nieuwe ArrayList (bron);

Hier geven we gewoon de bronlijst door aan de constructor van de bestemmingslijst, die een ondiepe kopie van de bronlijst maakt.

De bestemmingslijst is gewoon een andere verwijzing naar hetzelfde object waarnaar wordt verwezen door de bronlijst. Elke wijziging die door een verwijzing wordt aangebracht, heeft dus invloed op hetzelfde object.

Daarom is het gebruik van een constructor een goede optie voor het kopiëren van onveranderlijke objecten zoals Gehele getallen en Snaren.

4.3. Voeg alles toe

Een andere eenvoudige manier is om de Voeg alles toe methode van Lijst:

Lijstbestemming = nieuwe ArrayList (); bestemming.addAll (bron);

Het addAll method zal alle elementen van de bronlijst naar de bestemmingslijst kopiëren.

Er zijn een paar punten om op te merken met betrekking tot deze aanpak:

  1. Het maakt een ondiepe kopie van de bronnenlijst.
  2. De elementen van de bronlijst worden aan de bestemmingslijst toegevoegd.

4.4. Java 8 Streams

Java 8 heeft de Stream API geïntroduceerd, een geweldige tool om met Java te werken Collecties.

De ... gebruiken stroom() methode, maken we een kopie van de lijst met behulp van Stream API:

Lijstkopie = source.stream () .collect (Collectors.toList ());

4.5. Java 10

Kopiëren van een Lijst is nog eenvoudiger in Java 10. Met de kopie van() methode stelt ons in staat om een ​​onveranderlijke lijst te maken met de elementen van het gegeven Verzameling:

Lijstbestemming = List.copyOf (sourceList);

Als we voor deze aanpak willen gaan, moeten we ervoor zorgen dat de input Lijst niet nul en dat het er geen bevat nul elementen.

5. Conclusie

In dit artikel hebben we gekeken naar hoe en waarom de Collections.copy methode gooit IndexOutOfBoundException "Bron slaat niet op in bestemming". Daarnaast hebben we ook verschillende manieren onderzocht om een Lijst naar een ander Lijst.

Zowel de pre-Java-10-voorbeelden als de Java 10-voorbeelden zijn te vinden op GitHub.