Java: Реализация итератора для созданного пользователем класса HashSet.Семантика next () и hasNext ()? - PullRequest
1 голос
/ 23 марта 2012

взяв Java-класс, и мы должны разработать наш собственный класс HashSet.(без использования API JAVA)

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

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

Например, что произойдет, еслиу пользователя было несколько последовательных вызовов функции next () без 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 ]

3 голосов
/ 23 марта 2012

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

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

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

Просто следуйте API, как показано здесь http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Iterator.html

Если пользователь вызывает next () и элементов больше нет, вы генерируете исключение NoSuchElementException.

0 голосов
/ 23 марта 2012

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

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

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

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

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

...