logo

Ітератори в Java

Курсор Java — це ітератор, який використовується для повторення, обходу або отримання елементів об’єкта Collection або Stream один за одним. У цій статті ми дізнаємося про ітератори Java і їх роботу.

Курсори Java

Типи курсорів в Java

Є три курсори в Java, як зазначено нижче:

  1. Ітератор
  2. Перерахування
  3. ListIterator

Примітка: SplitIterator також можна розглядати як курсор, оскільки це лише тип ітератора.



1. Ітератор

Ітератори в Java використовуються в Рамка колекції щоб отримати елементи один за одним. Це універсальний ітератор, оскільки ми можемо застосувати його до будь-якого об’єкта Collection. Використовуючи Iterator, ми можемо виконувати як операції читання, так і видалення. Це вдосконалена версія Enumeration з додатковою функцією видалення елемента.

Ітератор потрібно використовувати щоразу, коли ми хочемо перерахувати елементи в усіх інтерфейсах, реалізованих фреймворком Collection, як-от Set, List, Queue, Deque, і всіх реалізованих класах інтерфейсу Map. Ітератор - це тільки Курсор доступний для всієї колекції. Об'єкт ітератора можна створити викликом ітератор() метод, присутній в інтерфейсі колекції.

Синтаксис

Iterator itr = c.  iterator  ();>

Примітка: Тут c — будь-який об’єкт колекції. itr має тип інтерфейсу Iterator і посилається на c.

ітератор java карти

Методи інтерфейсу ітератора в Java

Інтерфейс ітератора визначає три методи, перелічені нижче:

1. hasNext(): Повертає true, якщо ітерація містить більше елементів.

public boolean hasNext();>

2. наступний(): Повертає наступний елемент ітерації. Це кидає NoSuchElementException якщо більше немає елемента.

public Object next();>

3. видалити(): Видаляє наступний елемент ітерації. Цей метод можна викликати лише один раз за виклик next().

public void remove();>

Примітка: видалити() метод може викликати два винятки, а саме:

  • UnsupportedOperationException : Якщо операція видалення не підтримується цим ітератором
  • IllegalStateException : Якщо наступний метод ще не викликано, або метод видалення вже викликано після останнього виклику наступного методу.

Як ітератор Java працює всередині?

У цьому розділі ми спробуємо зрозуміти, як Java Iterator і його методи працюють внутрішньо. Щоб зрозуміти цю функцію, візьмемо наступний об’єкт LinkedList.

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

Тепер давайте створимо об’єкт Iterator на об’єкті List, як показано нижче:

Iterator citiesIterator = cities.iterator();>

Ітератор citiesIteartor виглядатиме так –

Ітератор Java Крок 1

Тут курсор ітератора вказує на перший елемент списку.

Тепер ми запустимо наступний фрагмент коду.

citiesIterator.hasNext(); citiesIterator.next();>
Ітератор Java, крок 2

Коли ми запускаємо наведений вище фрагмент коду, курсор ітератора вказує на перший елемент у списку, як показано на схемі вище.

Тепер ми запустимо наступний фрагмент коду.

citiesIterator.hasNext(); citiesIterator.next();>
Ітератор Java, крок 3

Коли ми запускаємо наведений вище фрагмент коду, курсор ітератора вказує на другий елемент у списку, як показано на схемі вище. Виконайте цей процес, щоб досягти курсору ітератора до кінцевого елемента списку.

Крок n ітератора Java

Після прочитання останнього елемента, якщо ми запустимо наведений нижче фрагмент коду, він поверне хибне значення.

citiesIterator.hasNext();>
Ітератор Java в кінці

Оскільки курсор ітератора вказує на кінцевий елемент списку, метод hasNext() повертає хибне значення.

Примітка: Переглянувши всі ці діаграми, ми можемо сказати, що Java Iterator підтримує лише ітерацію прямого напрямку, як показано на діаграмі нижче. Тому він також відомий як однонаправлений курсор.

Робота java Iterator

приклад

Java
// 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 = новий ArrayList (); // Ітерація списку для (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(); // Перевірка наступного елемента, де // умова виконується, доки в списку не залишиться єдиного елемента // за допомогою методу hasnext() while (itr.hasNext()) { // Переміщення курсора до наступного елемента int i = itr.next( ); // Отримання елементів по одному System.out.print(i + ' '); // Видалення непарних елементів if (i % 2 != 0) itr.remove(); } // Команда для наступного рядка System.out.println(); // Друк елементів всередині об'єкта System.out.println(al); } }>

Вихід
[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

Роздільники, як і інші ітератори, призначені для обходу елементів джерела. Джерелом може бути a Колекція , канал введення-виведення або функція генератора. Він включений до JDK 8 для підтримки ефективного паралельного проходження (паралельного програмування) на додаток до послідовного проходження. Інтерфейс Java Spliterator — це внутрішній ітератор, який розбиває потік на менші частини. Ці менші частини можна обробляти паралельно.

карта машинописом

Примітка: У реальному програмуванні нам ніколи не знадобиться використовувати Spliterator безпосередньо. За звичайних операцій він поводитиметься точно так само, як Java Iterator.

Переваги Java Iterator

  • Ми можемо використовувати його для будь-якого класу Collection.
  • Він підтримує операції READ і REMOVE.
  • Це Universal Cursor for Collection API.
  • Назви методів прості та зручні у використанні.

Обмеження Java Iterator

Крім того, існують певні обмеження Iterator, які перераховані нижче:

  • В операціях CRUD він НЕ підтримує операції CREATE та UPDATE.
  • Він підтримує лише ітерацію в прямому напрямку, яка є односпрямованим ітератором.
  • Порівняно з Spliterator, він НЕ підтримує ітерацію елементів паралельно, що означає, що він підтримує лише послідовну ітерацію.
  • Порівняно з Spliterator, він НЕ підтримує кращу продуктивність для ітерації великих обсягів даних.

2. Перерахування

Це інтерфейс, який використовується для отримання елементів застарілих колекцій (Вектор, Хеш-таблиця). Перерахування є першим ітератором з JDK 1.0, залишки включені в JDK 1.2 з більшою функціональністю. Перерахування також використовуються для визначення вхідних потоків для a SequenceInputStream . Ми можемо створити об’єкт Enumeration, викликавши елементи () метод векторного класу на будь-якому векторному об'єкті

Синтаксис

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

Є два методи в інтерфейсі Enumeration, а саме:

1. public boolean hasMoreElements(): Цей метод перевіряє, чи містить цей перелік більше елементів чи ні.

2. публічний об’єкт nextElement(): Цей метод повертає наступний елемент цього переліку. Він викидає NoSuchElementException, якщо відсутній інший елемент

приклад

Java
// 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 + ' '); } } }>

Вихід
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9>

Існують певні обмеження перерахування, а саме:

  • Перерахування для спадок лише класи (вектор, хеш-таблиця). Отже, це не універсальний ітератор.
  • Операції видалення не можна виконати за допомогою Enumeration.
  • Можлива лише ітерація в прямому напрямку.

Подібності між Java Enumeration та Iterator

  • Обидва є курсорами Java.
  • Обидва використовуються для ітерації колекції елементів об’єкта один за одним.
  • Обидва підтримують операцію READ або Retrieval.
  • Обидва є односпрямованими курсорами Java, що означає підтримку лише прямої ітерації.

Відмінності між Java Enumeration та Iterator

У наступній таблиці описано відмінності між Java Enumeration та Iterator:

ПерерахуванняІтератор
Введено в Java 1.0Введено в Java 1.2
Застарілий інтерфейсНе застарілий інтерфейс
Він використовується для ітерації лише класів Legacy Collection.Ми можемо використовувати його для будь-якого класу Collection.
Він підтримує лише операцію READ.Він підтримує як операції READ, так і DELETE.
Це не універсальний курсор.Це універсальний курсор.
Довгі назви методів.Прості та зручні у використанні назви методів.

3. Ітератор списку

Він застосовний лише для реалізованих класів колекції List, таких як ArrayList, LinkedList тощо. Він забезпечує двонаправлену ітерацію. ListIterator потрібно використовувати, коли ми хочемо пронумерувати елементи списку. Цей курсор має більше функцій (методів), ніж ітератор. Об’єкт ListIterator можна створити шляхом виклику listIterator() метод, присутній в інтерфейсі списку.

Синтаксис

ListIterator ltr = l.  listIterator  ();>

Примітка: Тут l — будь-який об’єкт List, ltr — тип. Інтерфейс ListIterator і посилається на l. Інтерфейс ListIterator розширює інтерфейс Iterator. Отже, усі три методи інтерфейсу Iterator доступні для ListIterator. Крім того, існують шість більше методів.

1. Напрямок вперед

1.1 hasNext(): Повертає true, якщо ітерація містить більше елементів

public boolean hasNext();>

1.2 далі(): Те саме, що метод next() ітератора. Повертає наступний елемент ітерації.

public Object next();>

1.3 nextIndex(): Повертає індекс наступного елемента або розмір списку, якщо ітератор списку знаходиться в кінці списку.

public int nextIndex();>

2. Зворотний напрямок

2.1 hasPrevious(): Повертає true, якщо ітерація має більше елементів під час руху назад.

public boolean hasPrevious();>

2.2 попередній(): Повертає попередній елемент у ітерації та може викидати NoSuchElementException якщо більше немає елемента.

public Object previous();>

2.3 попереднійіндекс(): Повертає індекс попереднього елемента або -1, якщо ітератор списку знаходиться на початку списку,

java хвіст
public int previousIndex();>

3. Інші методи

3.1 видалити(): Те саме, що метод remove() ітератора. Видаляє наступний елемент ітерації.

public void remove();>

3.2 set(Object obj): Замінює останній елемент, повернутий next() або previous(), на вказаний елемент.

стержень панди
public void set(Object obj);>

3.3 add(Object obj): Вставляє вказаний елемент у список у позицію перед елементом, який буде повернуто next()

public void add(Object obj);>

Очевидно, три методи, які ListIterator успадковується від Iterator ( hasNext() , наступний() , і видалити() ) робити те саме в обох інтерфейсах. The hasPrevious() а попередні операції є точними аналогами hasNext() і наступний() . Перші операції посилаються на елемент перед (неявним) курсором, тоді як останні посилаються на елемент після курсору. Попередня операція пересуває курсор назад, а наступна – вперед.

ListIterator не має поточного елемента; його позиція курсору завжди знаходиться між елементом, який буде повернуто викликом Попередній() і елемент, який буде повернуто викликом наступний().

1. набір() метод може створювати 4 винятки.

  • UnsupportedOperationException: якщо операція set не підтримується цим ітератором списку
  • ClassCastException: Якщо клас зазначеного елемента не дозволяє його додати до цього списку
  • IllegalArgumentException: Якщо якийсь аспект зазначеного елемента перешкоджає його додаванню до цього списку
  • IllegalStateException: Якщо ні наступний, ні попередній не були викликані, або видалення чи додавання були викликані після останнього виклику наступного чи попереднього

2. додати() метод може створювати 3 винятки.

  • UnsupportedOperationException: Якщо метод add не підтримується цим ітератором списку
  • ClassCastException: Якщо клас зазначеного елемента не дозволяє його додати до цього списку
  • IllegalArgumentException: Якщо якийсь аспект цього елемента перешкоджає його додаванню до цього списку

приклад

Java
// 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); } }>

Вихід
[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]>

Примітка: Так само є певні обмеження для ListIterator . Це найпотужніший ітератор, але він застосовний лише для реалізованих класів List, тому він не є універсальним ітератором.

Важливі моменти

  1. Зауважте, що спочатку будь-яке посилання ітератора вказуватиме на індекс безпосередньо перед індексом першого елемента в колекції.
  2. Ми не створюємо об’єкти Enumeration, Iterator, ListIterator, оскільки вони є інтерфейсами. Для створення об’єктів ми використовуємо такі методи, як elements(), iterator(), listIterator(). Ці методи мають анонімність Внутрішній клас який розширює відповідні інтерфейси та повертає цей об’єкт класу.

Примітка: The $ символ у назві еталонного класу є доказом того, що використовується концепція внутрішніх класів і створюються ці об’єкти класу.

Це можна перевірити за допомогою наведеного нижче коду. Щоб дізнатися більше про внутрішній клас, див

Java
// 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()); } }>

Вихід
java.util.Vector java.util.Vector$Itr java.util.Vector$ListItr>

Пояснення

У Java ітератор — це інтерфейс, який використовується для проходження колекції об’єктів по одному. Він використовується для проходження будь-якої структури даних на основі колекції, включаючи масиви, списки, набори та карти.

Ітератор має три основні методи, які використовуються для проходу по колекції:

  • hasNext() – цей метод перевіряє, чи є інший елемент у колекції, який можна повторити.
  • next() – цей метод повертає наступний елемент у колекції.
  • remove() – цей метод видаляє поточний елемент із колекції.

Інтерфейс Iterator є частиною Java Collection Framework і реалізований класами, які представляють різні типи колекцій.

програма

Java
import java.util.ArrayList; import java.util.Iterator; public class IteratorExample { public static void main(String[] args) { ArrayListімена = новий ArrayList(); names.add('Аліса'); names.add('Боб'); names.add('Чарлі'); names.add('Девід'); // Створення ітератора для списку імен Iteratorітератор = names.iterator(); // Ітерація по списку імен за допомогою ітератора while (iterator.hasNext()) { String name = iterator.next(); System.out.println(ім'я); } } }>

Вихід
Alice Bob Charlie David>

У цьому прикладі ми створили ArrayList рядків і додали до нього чотири імена. Потім ми створили ітератор для списку за допомогою методу iterator() класу ArrayList. Ми використовували метод hasNext(), щоб перевірити, чи є ще елементи в списку, які потрібно повторити, і метод next(), щоб отримати наступний елемент у списку. Ми надрукували кожен елемент за допомогою методу System.out.println().

Використання ітератора для проходу по колекції є зручним і ефективним способом ітерації по колекції, оскільки він дозволяє повторювати колекцію без знання внутрішньої структури колекції. Це також дозволяє видаляти елементи з колекції під час ітерації по ній.

Переваги Iterator в Java:

  • Ітератор — це простий і легкий у використанні інтерфейс, який дозволяє нам проходити колекцію, не відкриваючи її базову реалізацію.
  • Ітератор — це ефективний спосіб ітерації по колекції, особливо коли у нас є великий обсяг даних.
  • Ітератор забезпечує безпечний спосіб видалення елементів із колекції під час ітерації, не викликаючи жодних виняткових ситуацій одночасної модифікації.
  • Інтерфейс Iterator реалізовано всіма класами колекцій у Java, тому ми можемо використовувати той самий код для перебору різних типів колекцій.

Недоліки Iterator в Java:

Існують певні недоліки використання Iterator у Java, як зазначено нижче:

  • Ітератор — це односпрямований інтерфейс, що означає, що ми можемо рухатися лише вперед через колекцію. Ми не можемо рухатися назад або переходити до певного елемента.
  • Ітератор не є потокобезпечним, тому ми не можемо використовувати його для повторення колекції в багатопоточному середовищі без належної синхронізації.
  • Ітератор не надає жодного механізму для зміни елементів під час повторення колекції, окрім видалення елементів. Якщо нам потрібно змінити елементи, ми повинні використовувати інші інтерфейси, такі як ListIterator або простий цикл for.