dipu
dipu

Reputation: 1340

Should we avoid hasNext() call in an Iterator?

Is it advisable not to use iterator.hasNext() in looping over an iterator?

For example I would like to set value obj to each element of a list. I could use the following code or make it more readable by using hasNext() in a loop.

int size = list.size();
ListIterator<? super T> itr = list.listIterator();
for (int i=0; i<size; i++) {
     itr.next();
     itr.set(obj);
}

Instead of these lines I could write my code like the following.

for (ListIterator<? super T> itr = list.listIterator(); itr.hasNext(); ) {
    itr.next();
    itr.set(obj);
}

Upvotes: 3

Views: 3464

Answers (5)

Moritz Petersen
Moritz Petersen

Reputation: 13047

Of course, you should use hasNext(), but only for iterating over a collection, not for populating the collection. To fill the collection, work on the collection itself, not on it's iterator and to read from the collection use the for loop as described by @JMelnik.

Fill the collection

Collection<MyObject> list = ...;
while (something) {
    list.add(myObject);
}

Read the collection

for (MyObject myObject : list) {
    ...
}

Upvotes: 0

kyiu
kyiu

Reputation: 1976

When using an iterator, you should always call the hasNext() method. Otherwise, you may run into a NoSuchElementException when calling the next() method.

Upvotes: 0

mprabhat
mprabhat

Reputation: 20323

There is no such recommendation not to use hasNext.

The Iterator API list has just three methods, add, remove and hasNext

Also from clean code the second approach looks far better then the first one.

Upvotes: 1

d1e
d1e

Reputation: 6442

Well, when NetBeans refactor you for-each loop to use of iterators, they do it in following way.

for-each:

for (T object : list) {
}

iterator pattern:

for (Iterator<T> it = list.iterator(); it.hasNext();) {
    T object = it.next();
}

I think it is totally okay to use hasNext() on iterator while iterating.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500065

Is it advisable not to use iterator.hasNext() in looping over an iterator?

Um, no. hasNext is the standard way you iterate with an iterator. That's what the enhanced-for statement does behind the scenes for an iterable, for example.

Having said that, your code is already ListIterator-specific, as you're using ListIterator.set - so your second block of code won't actually compile at the moment. Even if it did, it wouldn't work, as you still need to call next(). This would work though:

for (ListIterator<? super T> itr = list.listIterator(); itr.hasNext(); ) {
    itr.next();
    itr.set(obj);
}

Upvotes: 7

Related Questions