2012-03-23 2 views
1

, принимая класс java, и мы должны создать собственный класс HashSet. (не используя JAVA apis)Java: реализация итератора для созданного пользователем класса HashSet. Семантика next() и hasNext()?

Мне нужно реализовать итератор для этого, и я смущен семантикой его использования.

Не уверен, что должен быть разрешен вызов в Next(), который будет перемещать индекс итератора, или если пользователь должен абсолютно использовать next() в сочетании с контуром hasNext(), который перемещает индекс.

Например, что произойдет, если у пользователя было несколько последовательных вызовов для следующего() без hasNext()?

Спасибо за помощь всем!

public class HashWordSet implements WordSet { 

private int size; 
private Node[] buckets = new Node[8]; 
//above is only provided for mention of variables 

    private class Node { 
    Word value; 
    Node next = null; 

    public Node(Word word) {value = word;} 
    public String toString() {return value.toString();} 
} 

class WordIterator implements Iterator<Word> { 

    private Node next; 
    private int index = 0; 

    public Word next() { 
     Node element = next; 
     if (element == null) 
      throw new NoSuchElementException(); 
     if ((next = element.next) == null) { 
      Node[] temp = buckets; 
      while (index < temp.length && (next = temp[index++]) == null) 
        ; 
     } 
     return element.value; 
    } 

    public boolean hasNext() { 
     return (next != null); 
    } 

ответ

3

Javadoc указывает, что если next называется и не существует следующий элемент, вы должны бросить NoSuchElementException. При этом вы не должны считать, что hasNext всегда вызывается до next - или что hasNext вызывается только один раз!

Типичный способ сделать это для хэш-таблицы является то, что

  1. hasNext прогресс через хэш-таблицу если это уже не указывает на действительный элемент.
  2. next в качестве первого шага вызывает hasNext, а после его завершения возвращает следующий элемент, увеличивает его до следующей позиции в хеш-таблице (без проверки, есть ли элемент в этой позиции).
+0

привет Луи, спасибо за разъяснение. Как вы думаете, вы могли бы указать мне в правильном направлении с фрагментом кода? спасибо – Wangagat

+0

Конечно: источник Java 'HashMap'. http://www.docjar.com/html/api/java/util/HashMap.java.html#791 –

+0

ОК, я изменил его на основе ссылки, которую вы отправили, но она по-прежнему не работает (обновлено выше) @ Andrzej Doyle – Wangagat

0

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

Фактически, hasNext() должен быть идемпотентным и по существу не должен изменять любое состояние вашего итератора вообще. Поскольку он не изменяет состояние, по определению он не может отличаться от того, был ли он ранее вызван или нет.

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

Что произойдет, если у пользователя было несколько последовательных вызовов для следующего() без hasNext()?

Если осталось и осталось достаточно элементов, он будет получать последовательные элементы, возвращенные при каждом вызове next(). Если он думает, что он лучше знает, и звонит next() после достижения конца итератора (т. Е. Когда hasNext() вернет false), то в соответствии с Javadocs вы должны выбросить NoSuchElementException.

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