Можем ли мы написать собственный итератор на Java?
104
Если у меня есть список, содержащий, [alice, bob, abigail, charlie]и я хочу написать итератор, который бы перебирал элементы, начинающиеся с 'a', могу ли я написать свой собственный? Как я могу это сделать ?
Конечно. Итератор - это просто реализация java.util.Iteratorинтерфейса. Если вы используете существующий итерационный объект (скажем, a LinkedList) из java.util, вам необходимо либо создать подкласс и переопределить его iteratorфункцию, чтобы вы вернули свою собственную, либо предоставить средство обертывания стандартного итератора в вашем специальном Iteratorэкземпляре (который имеет преимущество более широкого использования) и т. д.
хороший ответ .... +1 Однако вы не обязаны создавать подкласс LinkedList. Вы можете написать CustomIterator, экземпляр которого создается с помощью нового CustomIterator (somelist), поскольку интерфейсы ничего не говорят о конструкторах.
gd1 01
1
@Giacomo: Это то, что я имел в виду, говоря «... или предоставить средство обертывания стандартного итератора в вашем особом Iteratorэкземпляре ...» (и спасибо). :-)
TJ Crowder
197
Лучший вариант многократного использования - реализовать интерфейс Iterable и переопределить метод iterator ().
Вот пример класса типа ArrayList, реализующего интерфейс, в котором вы переопределяете метод Iterator ().
Этот класс реализует интерфейс Iterable с помощью Generics . Учитывая, что у вас есть элементы в массиве, вы сможете получить экземпляр Iterator, который, например, является необходимым экземпляром, используемым в цикле «foreach».
Вы можете просто создать анонимный экземпляр итератора без создания расширяющего Iterator и воспользоваться значением currentSize для проверки того, где вы можете перемещаться по массиву (допустим, вы создали массив с емкостью 10, но у вас есть только 2 элементы в 0 и 1). У экземпляра будет счетчик владельца, где он находится, и все, что вам нужно сделать, это поиграть с hasNext (), который проверяет, не является ли текущее значение нулевым, и next (), который вернет экземпляр вашего currentIndex. Ниже приведен пример использования этого API ...
publicstaticvoid main(String[] args){// create an array of type IntegerInteger[] numbers =newInteger[]{1,2,3,4,5};// create your list and hold the values.SOList<Integer> stackOverflowList =newSOList<Integer>(numbers);// Since our class SOList is an instance of Iterable, then we can use it on a foreach loopfor(Integer num : stackOverflowList){System.out.print(num);}// creating an array of StringsString[] languages =newString[]{"C","C++","Java","Python","Scala"};// create your list and hold the values using the same list implementation.SOList<String> languagesList =newSOList<String>(languages);System.out.println("");// Since our class SOList is an instance of Iterable, then we can use it on a foreach loopfor(String lang : languagesList){System.out.println(lang);}}// will print "12345//C//C++//Java//Python//Scala
Если хотите, вы также можете перебрать его, используя экземпляр Iterator:
// navigating the iteratorwhile(allNumbers.hasNext()){Integer value = allNumbers.next();if(allNumbers.hasNext()){System.out.print(value +", ");}else{System.out.print(value);}}// will print 1, 2, 3, 4, 5
Теперь, чтобы получить эффект того, что вам нужно, я думаю, вам нужно включить концепцию фильтра в итератор ... Поскольку итератор зависит от следующих значений, было бы трудно вернуть true в hasNext (), а затем отфильтруйте реализацию next () со значением, которое, например, не начинается с символа "a". Я думаю, вам нужно поиграть со вторичным Interator на основе отфильтрованного списка со значениями с данным фильтром.
Рекомендуется генерировать исключение неподдерживаемой операции из реализованных нами методов. Я думаю, что было бы неплохо выбросить исключение неподдерживаемой операции из метода remove ()!
даршан
2
Извините, @darshan, но это решение касается «как писать итераторы» ... Если бы акцент был на «написании идеально написанного кода», это было бы так!
Марчелло де Салес
непонятно, почему требуется проверка arrayList [currentIndex]! = null внутри hasNext (). может кто-нибудь объяснить.
Бхушан Кармаркар
12
Хороший пример для Iterable для вычисления факториала
FactorialIterable fi =newFactorialIterable(10);Iterator<Integer> iterator = fi.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}
Вы можете реализовать свой собственный Итератор. Ваш итератор может быть сконструирован так, чтобы обернуть итератор, возвращаемый List, или вы можете оставить курсор и использовать метод List get (int index). Вам просто нужно добавить логику в метод next вашего Iterator И метод hasNext, чтобы учесть ваши критерии фильтрации. Вам также нужно будет решить, будет ли ваш итератор поддерживать операцию удаления.
ListIterator - итератор для массива, который возвращает элементы, начинающиеся с 'a'.
Нет необходимости в реализации интерфейса Iterable. Но это возможно.
Нет необходимости реализовывать это в общем виде.
Он полностью удовлетворяет условиям контракта для hasNext () и next (). т.е. если hasNext () сообщает, что элементы все еще есть, next () вернет эти элементы. И если hasNext () сообщает, что элементов больше нет, он возвращает допустимое NoSuchElementExceptionисключение.
Ответы:
Конечно. Итератор - это просто реализация
java.util.Iterator
интерфейса. Если вы используете существующий итерационный объект (скажем, aLinkedList
) изjava.util
, вам необходимо либо создать подкласс и переопределить егоiterator
функцию, чтобы вы вернули свою собственную, либо предоставить средство обертывания стандартного итератора в вашем специальномIterator
экземпляре (который имеет преимущество более широкого использования) и т. д.источник
Iterator
экземпляре ...» (и спасибо). :-)Лучший вариант многократного использования - реализовать интерфейс Iterable и переопределить метод iterator ().
Вот пример класса типа ArrayList, реализующего интерфейс, в котором вы переопределяете метод Iterator ().
Этот класс реализует интерфейс Iterable с помощью Generics . Учитывая, что у вас есть элементы в массиве, вы сможете получить экземпляр Iterator, который, например, является необходимым экземпляром, используемым в цикле «foreach».
Вы можете просто создать анонимный экземпляр итератора без создания расширяющего Iterator и воспользоваться значением currentSize для проверки того, где вы можете перемещаться по массиву (допустим, вы создали массив с емкостью 10, но у вас есть только 2 элементы в 0 и 1). У экземпляра будет счетчик владельца, где он находится, и все, что вам нужно сделать, это поиграть с hasNext (), который проверяет, не является ли текущее значение нулевым, и next (), который вернет экземпляр вашего currentIndex. Ниже приведен пример использования этого API ...
Если хотите, вы также можете перебрать его, используя экземпляр Iterator:
Документация по foreach находится по адресу http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html . Вы можете взглянуть на более полную реализацию в моем личном практическом коде Google .
Теперь, чтобы получить эффект того, что вам нужно, я думаю, вам нужно включить концепцию фильтра в итератор ... Поскольку итератор зависит от следующих значений, было бы трудно вернуть true в hasNext (), а затем отфильтруйте реализацию next () со значением, которое, например, не начинается с символа "a". Я думаю, вам нужно поиграть со вторичным Interator на основе отфильтрованного списка со значениями с данным фильтром.
источник
for instance
это каламбур?Хороший пример для Iterable для вычисления факториала
Сокращенный код для Java 1.8
Пользовательский Iterable класс
Пользовательский класс Iterator
источник
Это полный код для написания итератора, который выполняет итерацию по элементам, начинающимся с 'a':
Пользовательский класс Iterator
источник
Вы можете реализовать свой собственный Итератор. Ваш итератор может быть сконструирован так, чтобы обернуть итератор, возвращаемый List, или вы можете оставить курсор и использовать метод List get (int index). Вам просто нужно добавить логику в метод next вашего Iterator И метод hasNext, чтобы учесть ваши критерии фильтрации. Вам также нужно будет решить, будет ли ваш итератор поддерживать операцию удаления.
источник
Вот полный ответ на вопрос.
ListIterator
- итератор для массива, который возвращает элементы, начинающиеся с 'a'.NoSuchElementException
исключение.источник