Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is an "infinite" iterator bad design? [closed]

Is it generally considered bad practice to provide Iterator implementations that are "infinite"; i.e. where calls to hasNext() always(*) return true?

Typically I'd say "yes" because the calling code could behave erratically, but in the below implementation hasNext() will return true unless the caller removes all elements from the List that the iterator was initialised with; i.e. there is a termination condition. Do you think this is a legitimate use of Iterator? It doesn't seem to violate the contract although I suppose one could argue it's unintuitive.

public class CyclicIterator<T> implements Iterator<T> {   private final List<T> l;   private Iterator<T> it;    public CyclicIterator<T>(List<T> l) {     this.l = l;     this.it = l.iterator();   }    public boolean hasNext() {     return !l.isEmpty();   }    public T next() {     T ret;      if (!hasNext()) {       throw new NoSuchElementException();     } else if (it.hasNext()) {       ret = it.next();     } else {       it = l.iterator();       ret = it.next();     }      return ret;   }    public void remove() {     it.remove();   } } 

(Pedantic) EDIT

Some people have commented how an Iterator could be used to generate values from an unbounded sequence such as the Fibonacci sequence. However, the Java Iterator documentation states that an Iterator is:

An iterator over a collection.

Now you could argue that the Fibonacci sequence is an infinite collection but in Java I would equate collection with the java.util.Collection interface, which offers methods such as size() implying that a collection must be bounded. Therefore, is it legitimate to use Iterator as a generator of values from an unbounded sequence?

like image 239
Adamski Avatar asked Apr 12 '10 14:04

Adamski


People also ask

Are infinite loops always bad?

No, they're not bad, they're actually useful. It depends whether you left some part of the code that eats up memory as the infinite loop proceeds. Infinite loops are used at almost everything: video games, networking, machine learning, etc.

Why iterator is better than for loop?

Iterator and for-each loop are faster than simple for loop for collections with no random access, while in collections which allows random access there is no performance change with for-each loop/for loop/iterator.

Can iterators be reused?

iterators are not reusable; you need to get a fresh Iterator from the Iterable collection each time you want to iterate over the elements.

What is the distinct advantage of using iterators over?

Iterator Advantage: Ability to remove elements from Collections. Ability to move forward and backward using next() and previous() . Ability to check if there more elements or not by using hasNext() .


1 Answers

I think it is entirely legitimate - an Iterator is just a stream of "stuff". Why should the stream necessarily be bounded?

Plenty of other languages (e.g. Scala) have the concept of unbounded streams built in to them and these can be iterated over. For example, using scalaz

scala> val fibs = (0, 1).iterate[Stream](t2 => t2._2 -> (t2._1 + t2._2)).map(_._1).iterator fibs: Iterator[Int] = non-empty iterator  scala> fibs.take(10).mkString(", ") //first 10 fibonnacci numbers res0: String = 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 

EDIT: In terms of the principle of least surprise, I think it depends entirely on the context. For example, what would I expect this method to return?

public Iterator<Integer> fibonacciSequence(); 
like image 136
oxbow_lakes Avatar answered Oct 10 '22 04:10

oxbow_lakes