Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - ListIterator and hasNext

I'm studying Java, and I've a problem with ListIterator. I've a List with these characters: b u o n g i o r n o. My code returns "buongiorno", while I was expecting it to print "buongiorn", without the trailing "o". I was expecting this because of the hasNext() function. My code uses recursion. Can you explain to me the reason?

public static String creaStringa(List<Character> lista) {
    System.out.println(lista.size());
    ListIterator<Character> it = lista.listIterator();
    return ricCrea(it);
}


public static String ricCrea(ListIterator<Character> it) {
    if(!(it.hasNext())) {
        return "";
    else
        return String.valueOf(it.next()) +ricCrea(it);
}
like image 526
testermaster Avatar asked Jun 14 '13 01:06

testermaster


People also ask

What is the difference next () and hasNext () method?

hasNext() either returns true or false while next() will actually iterate to the record.

What is ListIterator in Java?

In Java, ListIterator is an interface in Collection API. It extends Iterator interface. To support Forward and Backward Direction iteration and CRUD operations, it has the following methods. We can use this Iterator for all List implemented classes like ArrayList, CopyOnWriteArrayList, LinkedList, Stack, Vector, etc.

What is hasNext in Java?

The hasNext() method checks if the Scanner has another token in its input. A Scanner breaks its input into tokens using a delimiter pattern, which matches whitespace by default. That is, hasNext() checks the input and returns true if it has another non-whitespace character.

What is difference between iterator and ListIterator in Java?

Iterator can traverse only in forward direction whereas ListIterator traverses both in forward and backward directions. ListIterator can help to replace an element whereas Iterator cannot.


1 Answers

It would be more clear if the list had only one element, lets say "b". hasNext() would actually return true, and next() would read it and the iteration would end after that.

Explanation:

If you call Iterator<Object> it= list.iterator() on any non-empty list (even if it has only one element), you get true for calling the hasNext(). That is because the iterator is initialized BEFORE the first element:

  b u n g i o r n o
 ^
 i - iterator

And when you call next() it does two things:

  • it reads the element in front of the iterator,
  • moves the iterator just after the element that has been just read, and before the next one.

In your example - it prints "b" and stops before the "u":

  b u n g i o r n o 
   ^
   i

And just before the end:

  b u n g i o r n o
                 ^
                 i

It actually has the next value - "o". Calling the next() will read that value and jump after the o. There are no more elements. hasNext() will show false, and calling next() will result in an exception.

Technical details:

Basic idea how iterator is implemented is this: - when the Iterator is created by calling the iterator() on a List, its inner variable called next is pointing to the first element of the list. - hasNext() just checks whether the next is != null. - next() returns next and sets the next to show the next element.

This is java.util.ArrayList Iterator (with some details omitted):

public Iterator<E> iterator() {
     return new Itr();
}

private class Itr implements Iterator<E> {
     int cursor;       // index of next element to return
     int lastRet = -1; // index of last element returned; -1 if no such
     int expectedModCount = modCount;

     public boolean hasNext() {
         return cursor != size;
     }

     public E next() {
         checkForComodification();
         int i = cursor;
         Object[] elementData = ArrayList.this.elementData;
         cursor = i + 1;
         return (E) elementData[lastRet = i];
     }

 }
like image 190
darijan Avatar answered Sep 28 '22 08:09

darijan