"Hej, Amigo!"

"Hej, Ellie!"

"I dag vil jeg fortælle dig om iteratorer."

"Iteratorer blev opfundet praktisk talt samtidig med samlinger. Hovedformålet med samlinger er at gemme elementer, og hovedformålet med en iterator er at hente disse elementer en efter en."

"Hvad er så svært ved at få et sæt elementer?"

"For det første har elementerne i nogle samlinger, såsom Set, ikke en etableret rækkefølge, og/eller rækkefølgen ændres konstant."

"For det andet kan nogle datastrukturer gemme objekter på en meget kompleks måde: i forskellige grupper, lister osv. Med andre ord ville det være en ikke-triviel opgave at uddele alle elementerne i rækkefølge."

"For det tredje har samlinger en tendens til at ændre sig. Antag at du beslutter dig for at vise hele indholdet af en samling, men lige midt i outputtet skifter JVM til en anden tråd, der erstatter halvdelen af ​​samlingens elementer. Så i stedet for outputtet får du hvem ved hvad."

"Hmm..."

"Men! Det er netop den slags problemer, som en iterator kan løse. En iterator er et særligt objekt i en samling, der på den ene side har adgang til alle sine private data og kender sin interne struktur, og på den anden side , implementerer den offentlige Iterator-grænseflade, som lader alle vide, hvordan man arbejder med den. "

"Nogle iteratorer har et internt array, hvori alle elementer i samlingen kopieres, når iteratoren oprettes. Dette sikrer, at eventuelle efterfølgende ændringer af samlingen ikke påvirker antallet eller rækkefølgen af ​​elementerne."

"Jeg tror, ​​du er stødt på dette, når du arbejder med for hver . Du kan ikke samtidig loope over en samling og fjerne elementer fra den. Det er alt sammen netop på grund af den måde, en iterator fungerer på."

"I de nye samlinger, der er tilføjet samtidighedsbiblioteket, er iteratoren omarbejdet for at eliminere dette problem."

"Lad mig minde dig om, hvordan en iterator fungerer."

"Java har en speciel Iterator-grænseflade. Her er dens metoder:"

Metoder til Iterator<E>-grænsefladen Beskrivelse
boolean hasNext() Tjekker om der er flere elementer
E next() Returnerer det aktuelle element og flytter til det næste.
void remove() Fjerner det aktuelle element

"En iterator lader dig successivt få alle elementerne i en samling. Det er mere logisk at tænke på en iterator som noget som en InputStream - den har alle dataene, men dens opgave er at udlæse dem sekventielt."

"Den   næste () metode returnerer det næste element i samlingen."

" HasNext ()-metoden bruges til at kontrollere, om der er flere elementer."

"Og fjern () fjerner det aktuelle element."

"Nogen spørgsmål?"

"Hvorfor har metoderne så mærkelige navne? Hvorfor ikke isEmpty() og getNextElement()?"

"Ville det ikke give mere mening?"

"Det ville give mere mening, men navnene kom fra C++-sproget, hvor iteratorer dukkede op tidligere."

"Jeg kan se. Lad os fortsætte."

"Ud over en iterator er der også Iterable-grænsefladen, som skal implementeres af alle samlinger, der understøtter iteratorer. Den har en enkelt metode:"

Metoder til Iterable<T>-grænsefladen Beskrivelse
Iterator<T>iterator() Returnerer et iteratorobjekt

"Du kan bruge denne metode på enhver samling til at få et iteratorobjekt til at gå gennem dets elementer. Lad os gå over alle elementerne i et træsæt :"

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

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

"At bruge en iterator som denne er ikke særlig praktisk - der er for meget overflødig og åbenlys kode. Situationen blev enklere, da for -hver- løkken dukkede op i Java."

"Nu er denne kode meget mere kompakt og læsbar:"

Før Efter
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 kode! Iteratoren bruges i begge tilfælde."

"Det er bare, at dets brug er skjult i for-hver- løkken. Bemærk, at koden til højre ikke har nogen rød tekst overhovedet. Brugen af ​​iteratoren er fuldstændig skjult."

"En for-hver- løkke kan bruges til alle objekter, der understøtter iteratorer. Med andre ord kan du skrive din egen klasse, tilføje iterator ( )-metoden til den og bruge dens objekter i en for-each- konstruktion."

"Wow! Selvfølgelig er jeg ikke ivrig efter at skrive mine egne samlinger og iteratorer, men udsigten er stadig fristende. Jeg vil notere det."

Derudover er der en anden populær type iterator, der endda har sin egen grænseflade. Jeg taler om en iterator for lister, altså ListIterator .

"Uanset deres implementering opretholder lister rækkefølgen af ​​elementer, hvilket gør arbejdet med dem gennem en iterator lidt mere bekvemt."

"Her er metoderne til ListIterator <E>-grænsefladen:"

Metode Beskrivelse
boolean hasNext() Tjekker om der er flere elementer forude.
E next() Returnerer det næste element.
int nextIndex() Returnerer indekset for det næste element
void set(E e) Ændrer værdien af ​​det aktuelle element
boolean hasPrevious() Tjekker om der er elementer bagved.
E previous() Returnerer det forrige element
int previousIndex() Returnerer indekset for det forrige element
void remove() Fjerner det aktuelle element
void add(E e) Tilføjer et element til slutningen af ​​listen.

"Her kan vi med andre ord bevæge os både frem og tilbage. Og der er et par andre små funktioner."

"Nå, det er interessante ting. Hvor bruges det?"

"Antag, at du vil flytte frem og tilbage på en sammenkædet liste. Get-operationen vil være ret langsom, men den næste()-operation vil være meget hurtig."

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

"Tak, Ellie!"