logo

Iterátory v Javě

Kurzor Java je iterátor, který se používá k iteraci, procházení nebo načítání prvků objektu Collection nebo Stream jeden po druhém. V tomto článku se dozvíme o Java iterátorech a jak to funguje.

Kurzory Java

Typy kurzorů v Javě

Existují tři kurzory v Javě, jak je uvedeno níže:



  1. Iterátor
  2. Výčet
  3. ListIterator

Poznámka: SplitIterator lze také považovat za kurzor, protože jde pouze o typ Iterátoru.

1. Iterátor

Iterátory v Javě se používají v Kolektivní rámec k načtení prvků jeden po druhém. Je to a univerzální iterátor, protože jej můžeme použít na jakýkoli objekt Collection. Pomocí Iteratoru můžeme provádět operace čtení i odstraňování. Jedná se o vylepšenou verzi Enumeration s další funkcí odstranění prvku.

Iterátor je nutné použít vždy, když chceme vyjmenovat prvky ve všech rozhraních implementovaných v rámci Collection, jako je Set, List, Queue, Deque a všechny implementované třídy rozhraní Map. Iterátor je pouze kurzor dostupný pro celý rámec kolekce. Objekt iterátoru lze vytvořit voláním iterátor() metoda přítomná v rozhraní kolekce.



Syntax

Iterator itr = c.  iterator  ();>

Poznámka: Zde c je libovolný objekt kolekce. itr je rozhraní typu Iterator a odkazuje na c.

c pole řetězců

Metody rozhraní iterátoru v Javě

Rozhraní iterátoru definuje tři způsoby, jak jsou uvedeny níže:

1. hasNext(): Vrátí hodnotu true, pokud má iterace více prvků.



public boolean hasNext();>

2. další(): Vrátí další prvek v iteraci. To hází NoSuchElementException pokud není přítomen žádný další prvek.

public Object next();>

3. odstranit(): Odebere další prvek v iteraci. Tuto metodu lze volat pouze jednou za volání next().

public void remove();>

Poznámka: odstranit() metoda může vyvolat dvě výjimky a to takto:

  • UnsupportedOperationException : Pokud tento iterátor nepodporuje operaci odebrání
  • IllegalStateException : Pokud další metoda ještě nebyla zavolána, nebo pokud již byla zavolána metoda remove po posledním volání další metody.

Jak interně funguje Java Iterator?

V této části se pokusíme porozumět tomu, jak Java Iterator a jeho metody interně fungují. Vezměme si následující objekt LinkedList, abychom tuto funkci pochopili.

List cities = new LinkedList();  cities.add('G-1');  cities.add('G-2');  cities.add('G-3');  .  .  .  cities.add('G-n');>

Nyní vytvoříme objekt Iterator na objektu List, jak je znázorněno níže:

Iterator citiesIterator = cities.iterator();>

Iterátor citiesIteartor bude vypadat takto –

Java Iterator Krok 1

Kurzor iterátoru zde ukazuje před první prvek seznamu.

Nyní spustíme následující fragment kódu.

citiesIterator.hasNext(); citiesIterator.next();>
Java Iterator Krok 2

Když spustíme výše uvedený fragment kódu, kurzor iterátoru ukazuje na první prvek v seznamu, jak je znázorněno na výše uvedeném diagramu.

Nyní spustíme následující fragment kódu.

citiesIterator.hasNext(); citiesIterator.next();>
Java Iterator Krok 3

Když spustíme výše uvedený fragment kódu, kurzor iterátoru ukazuje na druhý prvek v seznamu, jak je znázorněno na výše uvedeném diagramu. Proveďte tento proces, abyste dosáhli kurzoru iterátoru na koncový prvek seznamu.

Java Iterator Krok č

Pokud po přečtení posledního prvku spustíme níže uvedený fragment kódu, vrátí hodnotu false.

citiesIterator.hasNext();>
Java Iterator na konci

Protože kurzor iterátoru ukazuje na poslední prvek seznamu, metoda hasNext() vrací falešnou hodnotu.

Poznámka: Po pozorování všech těchto diagramů můžeme říci, že Java Iterator podporuje pouze iteraci dopředného směru, jak je znázorněno na níže uvedeném diagramu. Proto je také známý jako jednosměrný kurzor.

pole slicing java
Práce s java iterátorem

Příklad

Jáva
// Java program to Demonstrate Iterator // Importing ArrayList and Iterator classes // from java.util package import java.util.ArrayList; import java.util.Iterator; // Main class public class Test { // Main driver method public static void main(String[] args) { // Creating an ArrayList class object // Declaring object of integer type ArrayList al = nový ArrayList (); // Iterace přes seznam pro (int i = 0; i< 10; i++) al.add(i); // Printing the elements in the List System.out.println(al); // At the beginning itr(cursor) will point to // index just before the first element in al Iterator itr = al.iterator(); // Kontrola dalšího prvku, kde // podmínka platí, dokud není v seznamu jediný prvek // pomocí metody hasnext() while (itr.hasNext()) { // Přesunutí kurzoru na další prvek int i = itr.next( ); // Získání prvků jeden po druhém System.out.print(i + ' '); // Odstranění lichých prvků if (i % 2 != 0) itr.remove(); } // Příkaz pro další řádek System.out.println(); // Tisk prvků uvnitř objektu System.out.println(al); } }>

Výstup
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9 [0, 2, 4, 6, 8]>

SplitIterator

Spliterátory, stejně jako ostatní iterátory, slouží k procházení prvků zdroje. Zdrojem může být a Sbírka , IO kanál nebo funkci generátoru. Je součástí JDK 8 pro podporu efektivního paralelního procházení (paralelního programování) vedle sekvenčního procházení. Rozhraní Java Spliterator je interní iterátor, který rozděluje stream na menší části. Tyto menší díly lze zpracovávat paralelně.

Poznámka: Při programování v reálném životě možná nikdy nebudeme muset používat přímo Spliterator. Za normálních operací se bude chovat úplně stejně jako Java Iterator.

Výhody Java Iteratoru

  • Můžeme jej použít pro jakoukoli třídu Collection.
  • Podporuje operace READ i REMOVE.
  • Jedná se o Universal Cursor for Collection API.
  • Názvy metod jsou jednoduché a snadno se používají.

Omezení Java Iteratoru

Také existují určitá omezení Iteratoru, která jsou uvedena následovně:

  • V CRUD Operations NEPODPORUJE operace CREATE a UPDATE.
  • Podporuje pouze iteraci směru vpřed, což je jednosměrný iterátor.
  • Ve srovnání se Spliteratorem NEPODPORUJE paralelní iteraci prvků, což znamená, že podporuje pouze sekvenční iteraci.
  • Ve srovnání s Spliteratorem NEPODPORUJE lepší výkon pro iteraci velkých objemů dat.

2. Výčet

Je to rozhraní používané k získání prvků starších kolekcí (Vector, Hashtable). Enumeration je první iterátor přítomný od JDK 1.0, resty jsou zahrnuty v JDK 1.2 s větší funkčností. Výčty se také používají k určení vstupních toků do a SequenceInputStream . Můžeme vytvořit objekt Enumeration voláním Prvky() metoda třídy vector na libovolném vektorovém objektu

Syntax

// Here 'v' is an Vector class object. e is of // type Enumeration interface and refers to 'v' Enumeration e =   v  .  elements  ();>

Existují dva metody v rozhraní Enumeration, konkrétně:

1. public boolean hasMoreElements(): Tato metoda testuje, zda tento výčet obsahuje více prvků nebo ne.

2. veřejný objekt nextElement(): Tato metoda vrátí další prvek tohoto výčtu. Pokud není přítomen žádný další prvek, vyvolá výjimku NoSuchElementException

Příklad

Jáva
// Java program to demonstrate Enumeration // Importing Enumeration and Vector classes // from java.util package import java.util.Enumeration; import java.util.Vector; // Main class public class Test { // Main driver method public static void main(String[] args) { // Creating a vector object Vector v = new Vector(); // Iterating over vector object for (int i = 0; i < 10; i++) v.addElement(i); // Printing elements in vector object System.out.println(v); // At beginning e(cursor) will point to // index just before the first element in v Enumeration e = v.elements(); // Checking the next element availability where // condition holds true till there is a single // element // remaining in the List while (e.hasMoreElements()) { // Moving cursor to next element int i = (Integer)e.nextElement(); // Print above elements in object System.out.print(i + ' '); } } }>

Výstup
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9>

Existují určitá omezení výčtu, která jsou následující:

  • Výčet je pro dědictví pouze třídy (vektor, hashtable). Nejedná se tedy o univerzální iterátor.
  • Operace odstranění nelze provádět pomocí Enumeration.
  • Je možná pouze iterace dopředného směru.

Podobnosti mezi Java Enumeration a Iterator

  • Oba jsou kurzory Java.
  • Oba se používají k iteraci kolekce prvků objektu jeden po druhém.
  • Oba podporují operaci READ nebo Retrieval.
  • Oba jsou jednosměrné kurzory Java, což znamená, že podporují pouze iteraci vpřed.

Rozdíly mezi Java Enumeration a Iterator

Následující tabulka popisuje rozdíly mezi Java Enumeration a Iterator:

VýčetIterátor
Představeno v Javě 1.0Představeno v Javě 1.2
Starší rozhraníNe starší rozhraní
Používá se k iteraci pouze tříd Legacy Collection.Můžeme jej použít pro jakoukoli třídu Collection.
Podporuje pouze operaci READ.Podporuje operace READ i DELETE.
Není to univerzální kurzor.Je to univerzální kurzor.
Zdlouhavé názvy metod.Jednoduché a snadno použitelné názvy metod.

3. ListIterator

Je použitelný pouze pro třídy implementované do kolekce List, jako je ArrayList, LinkedList atd. Poskytuje obousměrnou iteraci. ListIterator je nutné použít, když chceme vyjmenovat prvky seznamu. Tento kurzor má více funkcí (metod) než iterátor. Objekt ListIterator lze vytvořit voláním listIterator() metoda přítomná v rozhraní Seznam.

Syntax

ListIterator ltr = l.  listIterator  ();>

Poznámka: Zde l je libovolný objekt seznamu, ltr je typu. Rozhraní ListIterator a odkazuje na l. Rozhraní ListIterator rozšiřuje rozhraní Iterator. Takže všechny tři metody rozhraní Iterator jsou dostupné pro ListIterator. Kromě toho existují šest více metod.

1. Směr vpřed

1.1 hasNext(): Vrátí hodnotu true, pokud má iterace více prvků

public boolean hasNext();>

1.2 další(): Stejné jako metoda next() Iterátoru. Vrátí další prvek v iteraci.

public Object next();>

1.3 nextIndex(): Vrátí index dalšího prvku nebo velikost seznamu, pokud je iterátor seznamu na konci seznamu.

public int nextIndex();>

2. Směr vzad

2.1 hasPrevious(): Vrátí hodnotu true, pokud má iterace více prvků při procházení zpět.

public boolean hasPrevious();>

2.2 předchozí(): Vrátí předchozí prvek v iteraci a může hodit NoSuchElementException pokud není přítomen žádný další prvek.

public Object previous();>

2.3 previousIndex(): Vrátí předchozí index prvku nebo -1, pokud je iterátor seznamu na začátku seznamu,

pole seřazené v jazyce Java
public int previousIndex();>

3. Jiné metody

3.1 odstranit(): Stejné jako metoda remove() Iterátoru. Odebere další prvek v iteraci.

zkuste chytit v Javě
public void remove();>

3.2 sada (objekt objektu): Nahradí poslední prvek vrácený funkcí next() nebo previous() zadaným prvkem.

public void set(Object obj);>

3.3 add(Object obj): Vloží určený prvek do seznamu na pozici před prvkem, který by vrátil next()

public void add(Object obj);>

Je zřejmé, že tři metody, které ListIterator dědí z Iteratoru ( hasNext() , další() , a odstranit() ) dělat přesně to samé v obou rozhraních. The hasPrevious() a předchozí operace jsou přesnou analogií hasNext() a další() . První operace odkazují na prvek před (implicitním) kurzorem, zatímco druhá odkazuje na prvek za kurzorem. Předchozí operace přesune kurzor zpět, zatímco další jej posune dopředu.

ListIterator nemá žádný aktuální prvek; jeho pozice kurzoru vždy leží mezi prvkem, který by byl vrácen voláním předchozí() a prvek, který by byl vrácen voláním další().

1 set() metoda může vyvolat 4 výjimky.

  • UnsupportedOperationException: pokud operace nastavení není podporována tímto iterátorem seznamu
  • ClassCastException: Pokud třída zadaného prvku brání jeho přidání do tohoto seznamu
  • IllegalArgumentException: Pokud některý aspekt zadaného prvku brání jeho přidání do tohoto seznamu
  • IllegalStateException: Pokud po posledním hovoru na další nebo předchozí nebyl volán ani další, ani předchozí, nebo jste volali odebrat nebo přidat

2. přidat() metoda může vyvolat 3 výjimky.

  • UnsupportedOperationException: Pokud metoda add není podporována tímto iterátorem seznamu
  • ClassCastException: Pokud třída zadaného prvku brání jeho přidání do tohoto seznamu
  • IllegalArgumentException: Pokud některý aspekt tohoto prvku brání jeho přidání do tohoto seznamu

Příklad

Jáva
// Java program to demonstrate ListIterator // Importing ArrayList and List iterator classes // from java.util package import java.util.ArrayList; import java.util.ListIterator; // Main class public class Test { // Main driver method public static void main(String[] args) { // Creating an object of ArrayList class ArrayList al = new ArrayList(); // Iterating over Arraylist object for (int i = 0; i < 10; i++) // Adding elements to the Arraylist object al.add(i); // Print and display all elements inside object // created above System.out.println(al); // At beginning ltr(cursor) will point to // index just before the first element in al ListIterator ltr = al.listIterator(); // Checking the next element availability while (ltr.hasNext()) { // Moving cursor to next element int i = (Integer)ltr.next(); // Getting even elements one by one System.out.print(i + ' '); // Changing even numbers to odd and // adding modified number again in // iterator if (i % 2 == 0) { // Change to odd i++; // Set method to change value ltr.set(i); // To add ltr.add(i); } } // Print and display statements System.out.println(); System.out.println(al); } }>

Výstup
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9 [1, 1, 1, 3, 3, 3, 5, 5, 5, 7, 7, 7, 9, 9, 9]>

Poznámka: Podobně existují určitá omezení u ListIterator . Je to nejvýkonnější iterátor, ale je použitelný pouze pro třídy implementované do Seznamu, nejde tedy o univerzální iterátor.

Důležité body

  1. Upozorňujeme, že zpočátku bude jakýkoli odkaz iterátoru ukazovat na index těsně před indexem prvního prvku v kolekci.
  2. Nevytváříme objekty Enumeration, Iterator, ListIterator, protože jsou to rozhraní. K vytváření objektů používáme metody jako elements(), iterator(), listIterator(). Tyto metody mají anonym Vnitřní třída který rozšiřuje příslušná rozhraní a vrací tento objekt třídy.

Poznámka: The $ symbol v názvu referenční třídy je důkazem toho, že je použit koncept vnitřních tříd a tyto objekty třídy jsou vytvořeny.

To lze ověřit pomocí níže uvedeného kódu. Více o vnitřní třídě viz

Jáva
// Java program to demonstrate iterators references // Importing required classes from java.util package import java.util.Enumeration; import java.util.Iterator; import java.util.ListIterator; import java.util.Vector; // Main class public class GFG { // Main driver method public static void main(String[] args) { // Creating an object of Vector class Vector v = new Vector(); // Creating three iterators Enumeration e = v.elements(); Iterator itr = v.iterator(); ListIterator ltr = v.listIterator(); // Print class names of iterators // using getClass() and getName() methods System.out.println(e.getClass().getName()); System.out.println(itr.getClass().getName()); System.out.println(ltr.getClass().getName()); } }>

Výstup
java.util.Vector java.util.Vector$Itr java.util.Vector$ListItr>

Vysvětlení

V Javě je iterátor rozhraní, které se používá k procházení kolekcí objektů jeden po druhém. Používá se k iteraci libovolnou datovou strukturou založenou na kolekcích, včetně polí, seznamů, sad a map.

Iterátor má tři hlavní metody, které se používají k procházení kolekcí:

  • hasNext() – Tato metoda kontroluje, zda je v kolekci další prvek, který lze iterovat.
  • next() – Tato metoda vrací další prvek v kolekci.
  • remove() – Tato metoda odstraní aktuální prvek z kolekce.

Rozhraní Iterator je součástí Java Collection Framework a je implementováno třídami, které představují různé typy kolekcí.

Program

Jáva
import java.util.ArrayList; import java.util.Iterator; public class IteratorExample { public static void main(String[] args) { ArrayListjména = nový ArrayList(); jmena.add('Alice'); jmena.add('Bob'); jmena.add('Charlie'); jmena.add('David'); // Vytvoření iterátoru pro seznam jmen Iteratoriterator = jmena.iterator(); // Iterace přes seznam jmen pomocí iterátoru while (iterator.hasNext()) { String name = iterator.next(); System.out.println(jméno); } } }>

Výstup
Alice Bob Charlie David>

V tomto příkladu jsme vytvořili ArrayList řetězců a přidali do něj čtyři názvy. Poté jsme vytvořili iterátor pro seznam pomocí metody iterator() třídy ArrayList. Použili jsme metodu hasNext() ke kontrole, zda je v seznamu více prvků k iteraci, a metodu next() k získání dalšího prvku v seznamu. Každý prvek jsme vytiskli pomocí metody System.out.println().

Použití iterátoru k procházení kolekcí je pohodlný a efektivní způsob iterace kolekcí, protože umožňuje iteraci kolekce bez znalosti vnitřní struktury kolekce. Umožňuje také odstranění prvků z kolekce při jejím iterování.

Výhody Iteratoru v Javě:

  • Iterátor je jednoduché a snadno použitelné rozhraní, které nám umožňuje procházet kolekcí, aniž bychom odhalili její základní implementaci.
  • Iterátor je efektivní způsob, jak iterovat kolekci, zvláště když máme velké množství dat.
  • Iterátor poskytuje bezpečný způsob, jak odstranit prvky z kolekce během iterace, aniž by došlo k jakýmkoli výjimkám souběžných úprav.
  • Rozhraní Iterator je implementováno všemi třídami kolekcí v Javě, takže můžeme použít stejný kód k iteraci různých typů kolekcí.

Nevýhody Iteratoru v Javě:

Existují určité nevýhody použití Iteratoru v Javě, jak je uvedeno níže:

  • Iterátor je jednosměrné rozhraní, což znamená, že se můžeme pohybovat vpřed pouze kolekcí. Nemůžeme se posunout zpět nebo přeskočit na konkrétní prvek.
  • Iterátor není bezpečný pro vlákna, takže jej nemůžeme použít k iteraci kolekce ve vícevláknovém prostředí bez řádné synchronizace.
  • Iterátor neposkytuje žádný mechanismus pro úpravu prvků při iteraci nad kolekcí, kromě odstraňování prvků. Pokud potřebujeme upravit prvky, musíme použít jiná rozhraní jako ListIterator nebo jednoduchý cyklus for.