2016-05-24 3 views
2

Чтобы лучше узнать об Итераторах, я должен сам написать их, чтобы попытаться получить их правильную функциональность. У меня возникла проблема с правильной настройкой из предыдущего метода ListIterator.Правильная реализация методов List Iterator

Например, JavaDoc гласит:

Переменный вызовы следующий и предыдущий будет возвращать один и тот же элемент несколько раз.

Мой Итератор

class Node<Item> { 
    public Item data; 
    public Node<Item> next; 
    public Node<Item> previous; 

    public Node() { 
     data = null; 
     next = null; 
     previous = null; 
    } 

    public Node(Item i, Node<Item> n, Node<Item> p) { 
     data = i; 
     next = n; 
     previous = p; 
    } 
} 

public ListIterator<Item> listIterator() { 

    return new ListIterator<Item>() { 

     private Node<Item> n = first; 

     public boolean hasNext() { 
      return n.next != last; 
     } 

     public Item next() { 
      n = n.next; 
      return n.data; 
     } 

     //TODO 
     public void remove() { 
     } 

     public boolean hasPrevious() { 
      return n.previous != first; 
     } 

     public Item previous() { 
      n = n.previous; 
      return n.data; 
     } 
    }; 
} 

Теперь, когда я проверить это, у меня неправильное поведение с помощью метода previous().

TEST

LinkedList<String> lst2 = new LinkedList<String>(); 

    for (int i = 0; i < 4; i++) 
     lst2.add("" + "data".substring(i, i + 1)); 

    ListIterator<String> it2 = lst2.listIterator(); 
    System.out.println("\nTest the list iterator.\nThe test list is " + lst2 + "\n"); 

    while (it2.hasNext()) { 
     System.out.println("next is " + it2.next()); 
     System.out.println("previous is " + it2.previous()); 
     if (removeImplemented) { 
      it2.remove(); 
      System.out.println("After remove: " + lst2); 
     } 
     System.out.println("next is " + it2.next()); 
    } 

    System.out.println("\nHere is how the built-in Java ArrayList class works\n"); 
    ArrayList<String> lst3 = new ArrayList<String>(); 

    for (int i = 0; i < 4; i++) 
     lst3.add("" + "data".substring(i, i + 1)); 

    ListIterator<String> it3 = lst3.listIterator(); 
    System.out.println("Test list iterator.\nThe test list is " + lst3 + "\n"); 

    boolean remove = false; 

    while (it3.hasNext()) { 
     System.out.println("next is " + it3.next()); 
     System.out.println("previous is " + it3.previous()); 
     if (remove) { 
      it3.remove(); 
      System.out.println("After remove: " + lst3); 
     } 
     System.out.println("next is " + it3.next()); 
    } 

Мои результаты

The test list is [d, a, t, a] 

next is d 
previous is null //incorrect 
next is d 
next is a 
previous is d //incorrect 
next is a 
next is t 
previous is a //incorrect 
next is t 
next is a 
previous is t //incorrect 
next is a 

Правильные Результаты

The test list is [d, a, t, a] 

next is d 
previous is d 
next is d 
next is a 
previous is a 
next is a 
next is t 
previous is t 
next is t 
next is a 
previous is a 
next is a 

Теперь, к моему understandi ng, второй набор результатов - правильное поведение ListIterator. Итак, что я могу сделать для достижения такого поведения? Из того, что я прочитал, это связано с тем, что курсор перемещается в элемент раньше, а не сам элемент. У меня возникли проблемы с мыслью о том, как это реализовать.

+0

Javadoc ссылается на 'следующего()' и 'предыдущего()' 'методы Listiterator', но это выглядит, как вы возвращение полой' 'next' и предыдущие 'любого класса' Node n', таким образом, ваше поведение. –

+0

@ DanielWiddis так будет ли текущее поведение правильным? – 23k

+0

Зависит от того, что вы подразумеваете под «правильным». Если вы пытаетесь сопоставить «ListIterator», то, очевидно, нет, так как ваш результат не соответствует. Я не вижу, где вы обновляете n.data, значение которого вы возвращаете, поэтому я понятия не имею, что вы пытаетесь сделать под капотом. –

ответ

2

Вы правильно выполнили поведение для next(), продвигаясь к следующему узлу и возвращая новое значение.

Однако поведение для previous() должно вернуть существующее значение перед изменением на предыдущий узел. Вам нужно будет хранить n.data во временной переменной перед обновлением n, а затем вернуть сохраненное временное значение.

Например:

public Item previous() { 
    Item temp = n.data; 
    n = n.previous; 
    return temp; 
} 
+0

Есть ли способ показать пример?Хотя это имеет смысл, мне все еще не удается реализовать его в моем коде. – 23k

+0

@ 23k Я обновил свой ответ и включил конкретный пример. Кажется тривиальным, основываясь на том, что я объяснил. Есть ли еще одна проблема с кодом? –

+0

Где я должен обновлять temp? На первом проходе, 'n.data == null'. Поэтому каждый раз, когда temp возвращается в предыдущее, дается значение null. – 23k

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