2013-06-14 6 views
4

Я изучаю Java, и у меня проблема с ListIterator. У меня есть список с этими символами: b u o n g i o r n o. Мой код возвращает «buongiorno», в то время как я ожидал, что он напечатает «buongiorn», без конечного «o». Я ожидал этого из-за функции hasNext(). В моем коде используется рекурсия. Можете ли вы объяснить мне причину?Java - ListIterator и hasNext

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); 
} 

ответ

0

Когда итератор на последней «п» и ricCrea называется, то hasNext вернется true и next вернется «о».

Таким образом, вы можете написать что-то вроде:

public static String ricCrea(ListIterator<Character> it) { 
    if (it.hasNext()) { 
     Character c = it.next(); 
     if (it.hasNext()) { 
      return c + ricCrea(it); 
     } 
    } 
    return ""; 
} 
+0

Здравствуйте, благодарю вас за ответ. В моей итальянской книге написано «следующее возвращает значения положения итератора, а затем переводит итератор в следующую позицию». Это правильно? – testermaster

+0

@DanieleImpagliazzo No. Он возвращает следующее значение после текущей позиции. –

1

ListIterator.hasNext() вернется true последний «о» характере, а также (как и любой другой символ). Следовательно, else тоже будет выполнен. Только после того, как последнее «o» было получено, что hasNext() вернет false (поскольку он прошел все элементы сейчас).

Дело в том, что hasNext() проверяет только если что-то еще доступно для возврата по вызову . Он не получает или не пропускает его сам по себе.

+0

Здравствуйте, благодарю вас за ответ. В моей итальянской книге написано «следующее возвращает значения положения итератора, а затем переводит итератор в следующую позицию». Это правильно? – testermaster

+0

Просто небольшая коррекция: «' next() 'возвращает значение ** в текущей позиции ** итератора, а затем переводит итератор в следующую позицию». –

1

Итератор начинает «указывать» на предмет перед первым.

next() заставляет итератор указывать на следующий элемент и возвращать его.

Таким образом, вы фактически перебираете весь список.

Это для того, чтобы следующий синтаксис при переборе:

 
while (it.hasNext()) 
{ 
    ItemClass itemValue = it.next(); 
    // do something with the value 
} 

тот же синтаксис может быть использован даже если итератор пуст.

+0

Привет, благодарю вас за ответ. В моей итальянской книге написано «следующее возвращает значения положения итератора, а затем переводит итератор в следующую позицию». Так что это неправильно? – testermaster

+1

См. Здесь: http://docs.oracle.com/javase/6/docs/api/java/util/Iterator.html «Далее: возвращает следующий элемент в итерации». –

+1

Вещь с итератором заключается в том, что концептуально она не указывает ни на что. Существует только упорядоченный набор предметов, и вы можете получить следующий и узнать, есть ли еще. –

5

Было бы более ясно, если бы в списке был только один элемент, скажем, «b». hasNext() действительно вернет true, и next() прочитает его, и после этого итерация закончится.

Объяснение:

Если вы звоните Iterator<Object> it= list.iterator() на любой непустого списка (даже если он имеет только один элемент), вы получите true для вызова hasNext(). Это происходит потому, что итератор инициализируется перед первым элементом:

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

И когда вы звоните next() это делает две вещи:

  • считывает элемент перед итератора,
  • перемещает итератор сразу после элемента, который был только что прочитан, и до следующего.

В вашем примере - она ​​печатает "б" и останавливается перед "U":

b u n g i o r n o 
^
    i 

И только до конца:

b u n g i o r n o 
       ^
       i 

Это на самом деле имеет следующее значение - «о». Вызов next() будет читать это значение и прыгать после o. Больше нет элементов. hasNext() отобразит false, а вызов next() приведет к исключению.

Технические данные:

Основная идея, как реализуется итератора заключается в следующем: - когда Iterator создается путем вызова iterator() на List, его внутренняя переменная называется next указывает на первый элемент список. - hasNext() просто проверяет, next - != null. - next() возвращает next и устанавливает next, чтобы отобразить следующий элемент.

Это java.util.ArrayList Итератор (причем некоторые детали опущены):

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]; 
    } 

} 
+1

Хотя, легче понять, как работает Итератор, изображая его так: это неверно. Программно, вы не можете указывать курсор между двумя элементами, потому что он реализован как просто индекс. –

+0

'T next' указывает на элемент, а' hasNext() 'проверяет, есть ли' next! = Null', yadda, yadda, мы все знаем об этом, но это для лучшего понимания концепции. – darijan

+0

Да, но концепция должна быть понята правильно. –

0

hasnext() метод просто позволяет вам знать, если есть символ слева в списке или нет. next() - метод, который получает значение знака. Таким образом, hasnext() не увеличивает положение итератора. Он просто сообщает, есть ли какой-либо элемент в следующей позиции или нет, на основе которого вы можете вызвать next() или выполнить требуемую операцию.

Смежные вопросы