– Szia Amigo!
– Szia, Ellie!
– Ma az iterátorokról szeretnék mesélni.
"Az iterátorokat gyakorlatilag a gyűjteményekkel egy időben találták ki. A gyűjtemények fő célja az elemek tárolása, az iterátor fő célja pedig az, hogy ezeket az elemeket egyenként lekérje."
– Mi olyan nehéz egy elemkészlet beszerzésében?
"Először is, egyes gyűjteményekben, például a készletben az elemeknek nincs meghatározott sorrendje, és/vagy a sorrend folyamatosan változik."
"Másodszor, egyes adatstruktúrák nagyon összetett módon tárolhatják az objektumokat: különböző csoportokban, listákban stb. Más szóval, az összes elemet sorrendben kiosztani nem triviális feladat lenne."
"Harmadszor, a gyűjtemények általában változnak. Tegyük fel, hogy úgy dönt, hogy egy gyűjtemény teljes tartalmát megjeleníti, de a kimenet kellős közepén a JVM egy másik szálra vált, amely a gyűjtemény elemeinek felét lecseréli. Így a kimenet helyett azt kapja, hogy ki tudja mit."
"Hmm..."
"De! Pontosan ilyen problémákat tud megoldani egy iterátor. Az iterátor egy speciális objektum a gyűjteményben, amely egyrészt hozzáfér az összes privát adatához, és ismeri a belső szerkezetét, másrészt , megvalósítja a nyilvános Iterator felületet, amely lehetővé teszi, hogy mindenki tudja, hogyan kell vele dolgozni. "
"Néhány iterátor rendelkezik egy belső tömbbel, amelybe a gyűjtemény összes eleme az iterátor létrehozásakor másolódik. Ez biztosítja, hogy a gyűjtemény későbbi módosításai ne befolyásolják az elemek számát vagy sorrendjét."
"Szerintem találkoztál ezzel, amikor mindegyiknél dolgozol . Nem lehet egyszerre hurkolni egy gyűjteményt, és eltávolítani belőle elemeket. Ez pontosan az iterátor működése miatt van így."
"A párhuzamossági könyvtárhoz hozzáadott új gyűjteményekben az iterátort átdolgozták a probléma kiküszöbölése érdekében."
– Hadd emlékeztesselek az iterátor működésére.
"A Java speciális Iterator felülettel rendelkezik. Íme a módszerei:
Az Iterator<E> interfész módszerei | Leírás |
---|---|
boolean hasNext() |
Ellenőrzi, hogy vannak-e további elemek |
E next() |
Visszaadja az aktuális elemet, és a következőre lép. |
void remove() |
Eltávolítja az aktuális elemet |
"Egy iterátor lehetővé teszi a gyűjtemény összes elemének egymás utáni megszerzését. Logikusabb az iterátort úgy tekinteni, mint valami InputStream-et – az összes adatot tartalmazza, de az a feladata, hogy szekvenciálisan kiadja azokat."
"A következő () metódus a gyűjtemény következő elemét adja vissza."
"A hasNext () módszerrel ellenőrizhető, hogy vannak-e további elemek."
"És eltávolítás () eltávolítja az aktuális elemet."
"Bármi kérdés?"
"Miért van a metódusoknak ilyen furcsa neve? Miért nem az isEmpty() és a getNextElement()?"
– Nem lenne több értelme?
"Sokkal értelmesebb lenne, de a nevek a C++ nyelvből származtak, ahol korábban megjelentek az iterátorok."
– Értem. Folytassuk.
"Az iterátoron kívül létezik az Iterable felület is, amelyet minden iterátort támogató gyűjteménynek implementálnia kell. Egyetlen metódusa van:"
Az Iterable<T> interfész módszerei | Leírás |
---|---|
Iterator<T>iterator() |
Egy iterátor objektumot ad vissza |
"Ezt a módszert bármely gyűjteményben használhatja, hogy egy iterátor objektumot végigjárjon az elemein. Menjünk végig a TreeSet összes elemén :"
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();
while (iterator.hasNext())
{
String item = iterator.next();
System.out.println(item);
}
"Egy ilyen iterátor használata nem túl kényelmes – túl sok a felesleges és nyilvánvaló kód. A helyzet egyszerűbbé vált, amikor a for-each ciklus megjelent a Java-ban."
"Most ez a kód sokkal kompaktabb és olvashatóbb:"
Előtt | Után |
---|---|
|
|
"Ez ugyanaz a kód! Mindkét esetben az iterátort használják."
"Csak arról van szó, hogy a használata el van rejtve a for-each ciklusban. Vegye figyelembe, hogy a jobb oldali kódban egyáltalán nincs piros szöveg. Az iterátor használata teljesen rejtett."
"A for-each ciklus használható minden olyan objektumhoz, amely támogatja az iterátorokat. Más szóval, megírhatja saját osztályát, hozzáadhatja az iterátor () metódust, és használhatja az objektumokat egy for-each konstrukcióban."
"Hűha! Természetesen nem szívesen írok saját gyűjteményeimet és iterátoraimat, de a kilátás még mindig csábító. Megjegyzem."
Ezenkívül van egy másik népszerű iterátortípus, amely még saját felülettel is rendelkezik. Egy listák iterátoráról beszélek, azaz a ListIteratorról .
"Feldolgozásuktól függetlenül a listák megtartják az elemek sorrendjét, ami egy kicsit kényelmesebbé teszi velük az iterátoron keresztüli munkát."
"Íme a ListIterator <E> felületének metódusai :"
Módszer | Leírás |
---|---|
boolean hasNext() |
Ellenőrzi, hogy van-e további elem. |
E next() |
A következő elemet adja vissza. |
int nextIndex() |
A következő elem indexét adja vissza |
void set(E e) |
Módosítja az aktuális elem értékét |
boolean hasPrevious() |
Ellenőrzi, hogy vannak-e mögötte elemek. |
E previous() |
Az előző elemet adja vissza |
int previousIndex() |
Az előző elem indexét adja vissza |
void remove() |
Eltávolítja az aktuális elemet |
void add(E e) |
Hozzáad egy elemet a lista végéhez. |
"Más szóval, itt előre és hátra is haladhatunk. És van még egy-két apró tulajdonság."
"Nos, ez érdekes dolog. Hol használják?"
"Tegyük fel, hogy előre-hátra szeretne mozogni egy linkelt listán. A get művelet meglehetősen lassú lesz, de a next() művelet nagyon gyors lesz."
"Hmm. Meggyőztél. Szem előtt tartom."
– Köszönöm, Ellie!
GO TO FULL VERSION