Java: итераторы

#java #oop #iterator

#java #ооп #итератор

Вопрос:

Итак, я работаю над программой, которая включает в себя два типа данных: связанный список и Arraylist.

Итератор связанного списка выглядит следующим образом:

 private class NodeIterator implements Iterator<StudentIF> {
        private Node curr;

        public NodeIterator(Node head) {
            curr = head;
        }

        public void remove() { }

        public boolean hasNext() {
            if (curr == null)
                return false;
            return true;
        }

        public StudentIF next() {
            Node temp = curr;
            curr = curr.getNext();
            return temp.getData();
        }

    } // end class NodeIterator
  

и я вызываю метод / класс итератора ArrayList.

 MyArrayListName.iterator();
  

Вот метод, который выполняет работу по вызову итераторов:

 public StudentIF getStudent(int id) {
    Iterator<StudentIF> xy = iterator();
    while (xy.hasNext()) {
        if (id == xy.next().getId()) {
            return xy.next();
        }
    }
    // Student doesn't exist
    return null;
}
  

Моя проблема в том, что когда я вызываю свои методы, чтобы получить свой объект по их идентификатору (переменная экземпляра), он всегда захватывает СЛЕДУЮЩИЙ объект, а не тот, который мне нужен. Как мне получить текущий объект как со связанным списком, так и со списком массивов?

Пожалуйста, помогите мне!

Ответ №1:

Вероятно, поэтому вы используете next() метод дважды.

Попробуйте это

   while (xy.hasNext()) {
        StudentIF tmp = xy.next();
        if (id == tmp.getId()) {
            return tmp;
        }
  

Комментарии:

1. Возможно, вы также захотите упомянуть синтаксис for(StudentIF student : xy), который предотвратил бы проблему. Хороший ответ.

2. @ditkin … разве он не должен реализовать интерфейс Iterable, чтобы иметь возможность это делать?

Ответ №2:

Проблема в том, что вы вызываете .next() дважды в своем цикле здесь:

 if (id == xy.next().getId())
{
    return xy.next();
}
  

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

 StudentIF nextStudent = xy.next();
if (nextStudent.getId() == id)
{
    return nextStudent;
}
  

Комментарии:

1. Спасибо тебе, Брайан. Я принял ваш ответ из-за искупления; хорошее искупление! 🙂 У меня есть эта ошибка в другом месте, которую я исправляю; Спасибо за вашу помощь!

Ответ №3:

Каждый раз, когда вы используете метод next(), он увеличивает итератор, поэтому, вызывая

 if (id == xy.next().getId())
  

и

 return xy.next();
  

на самом деле вы увеличиваете итератор.

Лучше всего сохранить xy.next(), выполнить любые необходимые сравнения, а затем вернуть его следующим образом:

 public StudentIF getStudent(int id) {
Iterator<StudentIF> xy = iterator();
while (xy.hasNext()) {
    StudentIF student = xy.next();
    if (id == student.getId()) {
        return student;
    }
}
// Student doesn't exist
return null;
  

}

Ответ №4:

Вы вызываете .next() дважды.

Решением должно быть вызвать его только один раз и сохранить его в переменной, подобной этой:

  while (xy.hasNext()) {
        StudentIF student = xy.next();
        if (id == student.getId()) {
            return student;
        }
    }