2015-10-07 2 views
1

Мои выходы печатают null вместе с элементами, когда это не должно. Например,Метод Previous() класса ListIterator

 MyList<String> l = new MyList<String>(); 
     l.add("A"); 
     l.add("B"); 
     l.add("C"); 
     l.add("D"); 
     l.add("E"); 
     ListIterator<String> iter = l.listIterator(l.size()); 
     while(iter.hasPrevious()){ 
      Object element = iter.previous(); 
      System.out.print(element + " "); 
     } 

И результат:

null E D C B A 

Что случилось с методом предыдущего() и как я могу исправить, так что он не будет печатать null?

protected Node<T> beginMarker; // Dummy node marking the front of the list 
protected Node<T> endMarker; // Dummy node marking the back of the list 
.................... 
public class AListIterator implements ListIterator<T>{ 
     protected Node<T> current;     
     protected Node<T> lastVisited = null;  
     protected int expectedModCount = modCount; 
public boolean hasPrevious(){ 
      if(expectedModCount != modCount) 
       throw new ConcurrentModificationException(); 

      return current != beginMarker; 
     } 

public T previous(){ 
      if(expectedModCount != modCount) 
       throw new ConcurrentModificationException(); 
      if(!hasPrevious()) 
       throw new RuntimeException("Already at beginning of list"); 

      T prevItem = current.data; 
      current = current.prev; 
      return prevItem; 
     } 
+3

Я не думаю, что мы можем ответить, не видя весь класс списка. Мы не знаем, как инициализируется 'current', или есть ли что-то еще в коде, которое не позволяет правильно настроить список с двойной связью. – ajb

+0

'current' в' предыдущем' метод сначала относится к * текущему * узлу, а не к предыдущему: поэтому 'prevItem' присваивается данные * текущего * узла. Я подозреваю, что 'l.listIterator (l.size() - 1);' сделает результат «правильным», хотя это не исправление и просто скрывает проблему. – user2864740

+0

Учитывая приведенный код, 'previous()' должен вызывать 'NullPointerException', потому что' current' является 'null' в выражении' T prevItem = current.data; 'Если вы не получаете NPE там, вы должны быть инициализируя 'current', но делая это неправильно. Итак, показ этого кода важен. – erickson

ответ

1

Вам не нужен фиктивный маркер с обоих концов. Это связано с тем, что ListIterator для List длины n имеет только n + 1 возможных позиций курсора (перед каждым из элементов n и сразу после последних element). Поэтому вам нужен только один фиктивный узел.

Я бы избавился от endMarker и заменил его ссылкой на последний узел. Затем, когда вы вызываете l.listIterator(l.size()), вы получите итератор, где current изначально является последним узлом, поэтому вы не получите null в начале итерации.

+0

Все еще дает мне тот же результат :(@PaulBoddington –

+0

@KemalP. Я изменил свой ответ. Помогает ли это? –

1

Причиной вашей проблемы является неправильная инициализация тока. Когда начинается итерация (сразу после построения), ток должен указывать на последний элемент (когда указанная позиция равна размеру списка) или null, если нет предыдущих элементов (позиция 0 или пустой список).

Вам не нужен маркер начала. Ток станет нулевым после последнего вызова previous, поэтому вместо этого вы можете использовать простую нулевую проверку.

Вам также не нужен маркер конца (он все равно не используется в размещенном коде).

Btw, общее исключение для броска в случае итерации после конца - это исключение NoSuchElementException.

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