"Hei, Amigo!"

"Hei, Ellie!"

"I dag vil jeg fortelle deg om iteratorer."

"Iteratorer ble oppfunnet praktisk talt samtidig med samlinger. Hovedformålet med samlinger er å lagre elementer, og hovedformålet med en iterator er å hente disse elementene en etter en."

"Hva er så vanskelig med å få et sett med elementer?"

"For det første har ikke elementene i noen samlinger, for eksempel Set, en etablert rekkefølge og/eller rekkefølgen endres konstant."

"For det andre kan noen datastrukturer lagre objekter på en veldig kompleks måte: i forskjellige grupper, lister osv. Med andre ord, å dele ut alle elementene i rekkefølge ville være en ikke-triviell oppgave."

"For det tredje har samlinger en tendens til å endre seg. Anta at du bestemmer deg for å vise hele innholdet i en samling, men midt i utdataene bytter JVM til en annen tråd som erstatter halvparten av samlingens elementer. Så i stedet for utdataene, får du hvem vet hva."

"Hmm..."

"Men! Dette er nettopp den typen problemer som en iterator kan løse. En iterator er et spesielt objekt i en samling som på den ene siden har tilgang til alle sine private data og kjenner sin interne struktur, og på den andre siden. , implementerer det offentlige Iterator-grensesnittet, som lar alle vite hvordan de skal jobbe med det. "

"Noen iteratorer har en intern matrise der alle elementene i samlingen kopieres inn når iteratoren opprettes. Dette sikrer at eventuelle påfølgende endringer i samlingen ikke vil påvirke antallet eller rekkefølgen på elementene."

"Jeg tror du har kommet over dette når du jobber med for hver . Du kan ikke samtidig løkke over en samling og fjerne elementer fra den. Dette er nettopp på grunn av måten en iterator fungerer på."

"I de nye samlingene som er lagt til samtidighetsbiblioteket, er iteratoren omarbeidet for å eliminere dette problemet."

"La meg minne deg på hvordan en iterator fungerer."

"Java har et spesielt Iterator-grensesnitt. Her er metodene:"

Metoder for Iterator<E>-grensesnittet Beskrivelse
boolean hasNext() Sjekker om det er flere elementer
E next() Returnerer gjeldende element og går til neste.
void remove() Fjerner gjeldende element

"En iterator lar deg suksessivt få alle elementene i en samling. Det er mer logisk å tenke på en iterator som noe sånt som en InputStream - den har alle dataene, men dens oppgave er å sende den ut sekvensielt."

"Den   neste ()-metoden returnerer det neste elementet i samlingen."

" HasNext ()-metoden brukes til å sjekke om det er flere elementer."

"Og remove () fjerner det gjeldende elementet."

"Noen spørsmål?"

"Hvorfor har metodene så merkelige navn? Hvorfor ikke isEmpty() og getNextElement()?"

"Ville ikke det gi mer mening?"

"Det ville være mer fornuftig, men navnene kom fra C++-språket, der iteratorer dukket opp tidligere."

"Jeg skjønner. La oss fortsette."

"I tillegg til en iterator, er det også Iterable-grensesnittet, som må implementeres av alle samlinger som støtter iteratorer. Det har en enkelt metode:"

Metoder for Iterable<T>-grensesnittet Beskrivelse
Iterator<T>iterator() Returnerer et iteratorobjekt

"Du kan bruke denne metoden på en hvilken som helst samling for å få et iteratorobjekt til å gå gjennom elementene. La oss gå over alle elementene i et TreeSet :"

Eksempel
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}

"Å bruke en iterator som dette er ikke veldig praktisk - det er for mye overflødig og åpenbar kode. Situasjonen ble enklere da for -hver- løkken dukket opp i Java."

"Nå er denne koden mye mer kompakt og lesbar:"

Før Etter
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}
TreeSet<String> set = new TreeSet<String>();

for(String item : set)
{
 System.out.println(item);
}

"Dette er den samme koden! Iteratoren brukes i begge tilfeller."

"Det er bare det at bruken er skjult i for-hver- løkken. Merk at koden til høyre ikke har noen rød tekst i det hele tatt. Bruken av iteratoren er fullstendig skjult."

"En for-hver- løkke kan brukes for alle objekter som støtter iteratorer. Med andre ord kan du skrive din egen klasse, legge til iterator ( )-metoden til den, og bruke dens objekter i en for-each- konstruksjon."

"Wow! Selvfølgelig, jeg er ikke ivrig etter å skrive mine egne samlinger og iteratorer, men utsiktene er fortsatt fristende. Jeg skal notere det."

I tillegg er det en annen populær type iterator som til og med har sitt eget grensesnitt. Jeg snakker om en iterator for lister, altså ListIterator .

"Uavhengig av implementeringen deres, opprettholder lister rekkefølgen på elementene, noe som gjør det litt mer praktisk å jobbe med dem gjennom en iterator."

"Her er metodene for ListIterator <E>-grensesnittet:"

Metode Beskrivelse
boolean hasNext() Sjekker om det er flere elementer fremover.
E next() Returnerer neste element.
int nextIndex() Returnerer indeksen til neste element
void set(E e) Endrer verdien til det gjeldende elementet
boolean hasPrevious() Sjekker om det er noen elementer bak.
E previous() Returnerer forrige element
int previousIndex() Returnerer indeksen til forrige element
void remove() Fjerner gjeldende element
void add(E e) Legger til et element på slutten av listen.

"Med andre ord, her kan vi bevege oss både fremover og bakover. Og det er et par andre små funksjoner."

"Vel, det er interessante ting. Hvor brukes det?"

"Anta at du vil flytte frem og tilbake på en koblet liste. Get-operasjonen vil være ganske treg, men den neste()-operasjonen vil være veldig rask."

"Hmm. Du overbeviste meg. Jeg skal huske på det."

"Takk, Ellie!"