En guide til Iterator i Java

1. Introduktion

En Iterator er en af ​​mange måder, vi kan krydse en samling på, og som enhver mulighed har den sine fordele og ulemper.

Det blev først introduceret i Java 1.2 som erstatning for Tællinger og:

  • introducerede forbedrede metode navne
  • gjort det muligt at fjerne elementer fra en samling, som vi gentager
  • garanterer ikke iterationsbestilling

I denne vejledning gennemgår vi det enkle Iterator interface for at lære, hvordan vi kan bruge dens forskellige metoder.

Vi kontrollerer også det mere robuste ListIterator udvidelse, der tilføjer nogle interessante funktioner.

2. Den Iterator Interface

For at starte skal vi skaffe en Iterator fra en Kollektion; dette gøres ved at kalde iterator () metode.

For enkelheds skyld opnår vi Iterator forekomst fra en liste:

Listeelementer = ... Iterator iter = items.iterator ();

Det Iterator interface har tre kernemetoder:

2.1. hasNext ()

Det hasNext () metode kan bruges til at kontrollere, om der er mindst et element tilbage at gentage.

Det er designet til at blive brugt som en tilstand i mens sløjfer:

mens (iter.hasNext ()) {// ...}

2.2. Næste()

Det Næste() metode kan bruges til at gå over det næste element og opnå det:

Streng næste = iter.next ();

Det er god praksis at bruge hasNext () inden du prøver at ringe Næste().

Iteratorer til Samlinger garanterer ikke iteration i en bestemt rækkefølge, medmindre en særlig implementering giver det.

2.3. fjerne()

Endelig, hvis vi vil fjern det aktuelle element fra samlingen, vi kan bruge fjerne:

iter.remove ();

Dette er en sikker måde at fjerne elementer på, mens det gentages over en samling uden risiko for en ConcurrentModificationException.

2.4. Fuld Iterator Eksempel

Nu kan vi kombinere dem alle og se, hvordan vi bruger de tre metoder sammen til indsamlingsfiltrering:

while (iter.hasNext ()) {String next = iter.next (); System.out.println (næste); if ("TWO" .equals (next)) {iter.remove (); }}

Sådan bruger vi ofte en Iterator, vi kontrollerer på forhånd, om der er et andet element, vi henter det, og så udfører vi en handling på det.

2.5. Itererer med Lambda-udtryk

Som vi så i de foregående eksempler, er det meget detaljeret at bruge en Iterator når vi bare vil gennemgå alle elementerne og gøre noget med dem.

Siden Java 8 har vi forEachRemaining metode, der tillader brug af lambdas til behandling af resterende elementer:

iter.forEachRemaining (System.out :: println);

3. Den ListIterator Interface

ListIterator er en udvidelse, der tilføjer ny funktionalitet til iterering over lister:

ListIterator listIterator = items.listIterator (items.size ());

Læg mærke til, hvordan vi kan give en startposition, som i dette tilfælde er slutningen af Liste.

3.1. hasPrevious () og Tidligere()

ListIterator kan bruges til bagudkørsel, så det giver ækvivalenter af hasNext () og Næste():

while (listIterator.hasPrevious ()) {String forrige = listIterator.previous (); }

3.2. næsteIndex () og previousIndex ()

Derudover kan vi krydse indekser og ikke faktiske elementer:

Streng nextWithIndex = items.get (listIterator.nextIndex ()); String previousWithIndex = items.get (listIterator.previousIndex ());

Dette kan vise sig meget nyttigt, hvis vi har brug for at kende indekserne for de objekter, vi i øjeblikket ændrer, eller hvis vi vil registrere fjernede elementer.

3.3. tilføje()

Det tilføje metode, som, som navnet antyder, giver os mulighed for at tilføje et element inden den vare, der ville blive returneret af Næste() og efter at den ene kom tilbage Tidligere():

listIterator.add ("FOUR");

3.4. sæt()

Den sidste metode, der er værd at nævne, er sæt(), som lader os erstatte det element, der blev returneret i opkaldet til Næste() eller Tidligere():

Streng næste = listIterator.next (); hvis ("ONE". er lig med (næste)) {listIterator.set ("SWAPPED"); }

Det er vigtigt at bemærke det dette kan kun udføres, hvis der ikke er nogen tidligere opkald til tilføje() eller fjerne() blev lavet.

3.5. Fuld ListIterator Eksempel

Vi kan nu kombinere dem alle for at lave et komplet eksempel:

ListIterator listIterator = items.listIterator (); while (listIterator.hasNext ()) {String nextWithIndex = items.get (listIterator.nextIndex ()); Streng næste = listIterator.next (); if ("REPLACE ME" .equals (next)) {listIterator.set ("REPLACED"); }} listIterator.add ("NEW"); while (listIterator.hasPrevious ()) {String previousWithIndex = items.get (listIterator.previousIndex ()); String forrige = listIterator.previous (); System.out.println (forrige); }

I dette eksempel starter vi med at få ListIterator fra Liste, så kan vi få det næste element enten ved indeks -hvilket ikke øger iteratorens interne aktuelle element - eller ved at ringe Næste.

Så kan vi erstatte en bestemt vare med sæt og indsæt en ny med tilføje.

Når vi har nået slutningen af ​​iterationen, kan vi gå tilbage for at ændre yderligere elementer eller blot udskrive dem fra bund til top.

4. Konklusion

Det Iterator interface giver os mulighed for at ændre en samling, mens vi krydser den, hvilket er sværere med en enkel til / mens udsagn. Dette giver os igen et godt mønster, som vi kan bruge i mange metoder, der kun kræver behandling af samlinger, samtidig med at vi opretholder god samhørighed og lav kobling.

Endelig er den fulde kildekode som altid tilgængelig på GitHub.