Java IndexOutOfBoundsException “Kilde passer ikke til Dest”

1. Oversigt

I Java fremstiller du en kopi af en Liste kan undertiden producere en IndexOutOfBoundsException: “Kilde passer ikke til dest”. I denne korte vejledning skal vi se på, hvorfor vi får denne fejl, når vi bruger Collections.copy metode og hvordan den kan løses. Vi vil også se på alternativer til Collections.copy at lave en kopi af listen.

2. Reproduktion af problemet

Lad os starte med en metode til at oprette en kopi af en Liste bruger Collections.copy metode:

statisk liste copyList (List source) {List destination = new ArrayList (source.size ()); Collections.copy (destination, kilde); retur destination }

Her, den copyList metoden opretter en ny liste med en indledende kapacitet svarende til størrelsen på kildelisten. Derefter forsøger den at kopiere elementerne i kildelisten til destinationslisten:

Liste kilde = Arrays.asList (1, 2, 3, 4, 5); Liste kopi = copyList (kilde);

Men når vi først ringer til copyList metode, det kaster en undtagelse java.lang.IndexOutOfBoundsException: Kilde passer ikke til dest.

3. Årsag til Undtagelse

Lad os prøve at forstå, hvad der gik galt. I henhold til dokumentationen til Collections.copy metode:

Destinationslisten skal være mindst lige så lang som kildelisten. Hvis det er længere, påvirkes de resterende elementer på destinationslisten.

I vores eksempel har vi oprettet en ny Liste ved hjælp af en konstruktør med en indledende kapacitet svarende til størrelsen på kildelisten. Det tildeler simpelthen nok hukommelse og definerer faktisk ikke elementer. Størrelsen på den nye liste forbliver nul, fordi kapaciteten og størrelsen er forskellige attributter for Liste.

Derfor, når Collections.copy metode forsøger at kopiere kildelisten til destinationslisten, den kaster den java.lang.IndexOutOfBoundsException.

4. Løsninger

4.1. Collections.copy

Lad os se på et fungerende eksempel for at kopiere en Liste til en anden Liste, bruger Collections.copy metode:

Liste destination = Arrays.asList (1, 2, 3, 4, 5); Liste kilde = Arrays.asList (11, 22, 33); Collections.copy (destination, kilde);

I dette tilfælde kopierer vi alle tre elementer på kildelisten til destinationslisten. Det Arrays.asList metode initialiserer listen med elementer og ikke kun en størrelse, derfor er vi i stand til at kopiere kildelisten til destinationslisten med succes.

Hvis vi bare bytter argumenter fra Collections.copy metode, vil det kaste java.lang.IndexOutOfBoundsException fordi størrelsen på kildelisten er mindre end størrelsen på destinationslisten.

Efter denne kopieringshandling ser destinationslisten ud:

[11, 22, 33, 4, 5]

Sammen med Collections.copy metode, er der andre måder i Java at lave en kopi af Liste. Lad os se på nogle af dem.

4.2. ArrayList Konstruktør

Den enkleste metode til at kopiere en Liste bruger en konstruktør, der tager en Kollektion parameter:

Liste kilde = Arrays.asList (11, 22, 33); Liste destination = ny ArrayList (kilde);

Her videregiver vi simpelthen kildelisten til konstruktøren af ​​destinationslisten, som opretter en lav kopi af kildelisten.

Destinationslisten er blot endnu en henvisning til det samme objekt, som kildelisten refererer til. Så enhver ændring foretaget ved enhver henvisning vil påvirke det samme objekt.

Brug af en konstruktør er derfor en god mulighed for at kopiere uforanderlige objekter som Heltal og Strenge.

4.3. tilføjAlle

En anden enkel måde er at bruge tilføjAlle metode til Liste:

Liste destination = ny ArrayList (); destination.addAll (kilde);

TilføjAlle metode kopierer alle elementerne i kildelisten til destinationslisten.

Der er et par punkter at bemærke vedrørende denne tilgang:

  1. Det opretter en lav kopi af kildelisten.
  2. Elementerne i kildelisten føjes til destinationslisten.

4.4. Java 8 Strømme

Java 8 har introduceret Stream API, som er et fantastisk værktøj til at arbejde med Java Samlinger.

Bruger strøm() metode laver vi en kopi af listen ved hjælp af Stream API:

Liste kopi = source.stream () .collect (Collectors.toList ());

4.5. Java 10

Kopiering a Liste er endnu enklere i Java 10. Brug af copyOf () metode giver os mulighed for at oprette en uforanderlig liste, der indeholder elementerne i det givne Kollektion:

List destination = List.copyOf (sourceList);

Hvis vi vil gå med denne tilgang, er vi nødt til at sikre input Liste ikke er nul og at den ikke indeholder nogen nul elementer.

5. Konklusion

I denne artikel så vi på, hvordan og hvorfor Collections.copy metoden kaster IndexOutOfBoundException “Kilde arkiveres ikke i dest”. Sammen med det undersøgte vi også forskellige måder at kopiere en Liste til en anden Liste.

Både eksemplerne før Java-10 og eksemplerne Java 10 kan findes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found