Подтвердить что ты не робот

Как я могу ссылаться на текущий объект в итераторе

Я пытаюсь реализовать метод поиска в TreeSet. Используя итератор с условием, я хотел бы иметь возможность запускать набор и печатать объект, соответствующий условию. Однако способ, которым я это делаю в данный момент, - это распечатать последующий объект, а не текущий. Это то, что у меня есть до сих пор:

public void getDetails() {
        Iterator<Person> it = this.getPersonSet().iterator();
        System.out.println("Enter First Name");
        String first = in.next().toLowerCase();
        System.out.println("Enter Second Name");
        String last = in.next().toLowerCase();

        while (it.hasNext()) {
            if (it.next().getLast().toLowerCase().equals(last)) {
                Person p = it.next();
                System.out.println(p);
            }
        }

    }

Любая помощь будет отличной

4b9b3361

Ответ 1

Это то, что вы хотели бы сделать:

while (it.hasNext()) {
            Person p = it.next();
            if (p.getLast().toLowerCase().equals(last)) {
                System.out.println(p);
            }
        }

Ответ 2

Как я могу ссылаться на текущий объект в итераторе

Для записи API Iterator не позволяет вам это делать. Не существует понятия "текущего" объекта. Метод Iterator.next() дает вам следующий объект... и движется дальше.

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

Решение состоит в том, чтобы назначить результат вызова it.next() временной переменной, как описано принятым ответом.


Я не знаю точно, почему дизайнеры не включили понятие "текущего" объекта в API, но я могу подумать о нескольких причинах:

  • Это сделает типичный объект итератора более крупным; то есть дополнительное поле для хранения текущего объекта.
  • Это означало бы более 1 метод для класса Iterator для реализации.
  • Понятие текущего объекта плохо соответствует модели "курсора", задокументированной в интерфейсе ListIterator... и подразумевается текущим дизайном Iterator.
  • Существует небольшая проблема, связанная с тем, что Итератор "висит на" текущем объекте, тем самым предотвращая его от GC.
  • В большинстве случаев использования итератора не требуется текущий объект.
  • Есть другие способы справиться с этим.

Звучит как хороший звонок...

Ответ 3

Если вам нужна существующая реализация, вы можете использовать те из Google Guava или Коллекции сообщества Apache.
Другие ответы проще для вашей простой проблемы, но если вам нужно передать итератор вокруг и отслеживать последний элемент, возвращенный next(), это поможет.

Вот пример использования Guava с кодом OP (предполагается, что Person имеет метод String toLowerCase()):

import com.google.common.collect.PeekingIterator;
import static com.google.common.collect.Iterators.peekingIterator;

public void getDetails() {
    PeekingIterator<Person> it = peekingIterator(this.getPersonSet().iterator());
    System.out.println("Enter First Name");
    String first = in.next().toLowerCase();
    System.out.println("Enter Second Name");
    String last = in.next().toLowerCase();

    while (it.hasNext()) {
        // note the usage of peek() instead of next()
        if (it.peek().getLast().toLowerCase().equals(last)) {
            Person p = it.next();
            System.out.println(p);
        }
    }

}

Ответ 4

Удерживайте ссылку объекта в отдельном var:

Person current = it.next();
current.methodOne();
current.methodTwo();

Когда вы закончите с текущим значением, повторите его следующее

...
// done? 
current = it.next();

В цикле выглядит:

while( it.hasNext() ) { 
   Person current = it.next();
   current.doA();
   current.doB();
   current.doC();
 }

Ответ 5

метод next() возвращает текущий объект, например так:

private class IterSinglyLinked implements SimpleIterator<T> {
    Element curr = head;        // next element to return

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

    public T next() throws Exception {
        if (curr == null) throw new Exception("no more elements");
        T data = curr.data;
        curr = curr.next;
        return data;
    }
}

Если он вернет следующий, а не текущий, он не сможет добраться до самого первого.