Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we write our own iterator in Java?

Tags:

java

iterator

If I have a list containing [alice, bob, abigail, charlie] and I want to write an iterator such that it iterates over elements that begin with 'a', can I write my own ? How can I do that ?

like image 269
phoenix Avatar asked May 01 '11 15:05

phoenix


People also ask

How do I make my own iterator?

To create an iterator object on your own it is necessary to implement the __iter__() and __next__() methods. The __iter__() method will always return the iterator object itself. We can initialize variables in this method. The __next__() method is created to return the next element from the iterator.

How do I make an iterator in Java?

To implement an Iterator, we need a cursor or pointer to keep track of which element we currently are on. Depending on the underlying data structure, we can progress from one element to another. This is done in the next() method which returns the current element and the cursor advances to next element.

How do you use a custom iterator?

To use custom iterators, you must create an Apex class that implements the Iterator interface. Returns true if there's another item in the collection being traversed, false otherwise. Returns the next item in the collection. All methods in the Iterator interface must be declared as global or public .

Do you have to import iterator in Java?

An Iterator is an object that can be used to loop through collections, like ArrayList and HashSet. It is called an "iterator" because "iterating" is the technical term for looping. To use an Iterator, you must import it from the java.


2 Answers

The best reusable option is to implement the interface Iterable and override the method iterator().

Here's an example of a an ArrayList like class implementing the interface, in which you override the method Iterator().

import java.util.Iterator;  public class SOList<Type> implements Iterable<Type> {      private Type[] arrayList;     private int currentSize;      public SOList(Type[] newArray) {         this.arrayList = newArray;         this.currentSize = arrayList.length;     }      @Override     public Iterator<Type> iterator() {         Iterator<Type> it = new Iterator<Type>() {              private int currentIndex = 0;              @Override             public boolean hasNext() {                 return currentIndex < currentSize && arrayList[currentIndex] != null;             }              @Override             public Type next() {                 return arrayList[currentIndex++];             }              @Override             public void remove() {                 throw new UnsupportedOperationException();             }         };         return it;     } } 

This class implements the Iterable interface using Generics. Considering you have elements to the array, you will be able to get an instance of an Iterator, which is the needed instance used by the "foreach" loop, for instance.

You can just create an anonymous instance of the iterator without creating extending Iterator and take advantage of the value of currentSize to verify up to where you can navigate over the array (let's say you created an array with capacity of 10, but you have only 2 elements at 0 and 1). The instance will have its owner counter of where it is and all you need to do is to play with hasNext(), which verifies if the current value is not null, and the next(), which will return the instance of your currentIndex. Below is an example of using this API...

public static void main(String[] args) {     // create an array of type Integer     Integer[] numbers = new Integer[]{1, 2, 3, 4, 5};      // create your list and hold the values.     SOList<Integer> stackOverflowList = new SOList<Integer>(numbers);      // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop     for(Integer num : stackOverflowList) {         System.out.print(num);     }      // creating an array of Strings     String[] languages = new String[]{"C", "C++", "Java", "Python", "Scala"};      // create your list and hold the values using the same list implementation.     SOList<String> languagesList = new SOList<String>(languages);      System.out.println("");     // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop     for(String lang : languagesList) {         System.out.println(lang);     } } // will print "12345 //C //C++ //Java //Python //Scala 

If you want, you can iterate over it as well using the Iterator instance:

// navigating the iterator while (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 

The foreach documentation is located at http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html. You can take a look at a more complete implementation at my personal practice google code.

Now, to get the effects of what you need I think you need to plug a concept of a filter in the Iterator... Since the iterator depends on the next values, it would be hard to return true on hasNext(), and then filter the next() implementation with a value that does not start with a char "a" for instance. I think you need to play around with a secondary Interator based on a filtered list with the values with the given filter.

like image 198
Marcello de Sales Avatar answered Oct 09 '22 06:10

Marcello de Sales


Sure. An iterator is just an implementation of the java.util.Iterator interface. If you're using an existing iterable object (say, a LinkedList) from java.util, you'll need to either subclass it and override its iterator function so that you return your own, or provide a means of wrapping a standard iterator in your special Iterator instance (which has the advantage of being more broadly used), etc.

like image 41
T.J. Crowder Avatar answered Oct 09 '22 07:10

T.J. Crowder