2017-06-18 42 views
0

我在學習Java第6版中的數據結構和算法時嘗試自己構建鏈接位置列表。 Position實現Node來存儲數據。 我想構建兩個迭代器,一個用於迭代位置,另一個用於迭代位置中的元素。所以我認爲2種for-each循環可以作爲以下應用:java迭代器無法應用於for_each

LinkedPositionalList<String> list = new LinkedPositionalList<>(); 
    list.addFirst("A"); 
    list.addLast("B"); 
    list.addLast("V"); 
    for (Position posi : list.positions()) { 
    } 
    for (String str:list) { 
    } 

事實證明,第二次爲-各不適用輸入,但第一個運作良好。那麼如何讓每個迭代器的第二個工作?

這是我建立這樣的類的代碼: ps:代碼很長。嵌套類的最後一部分試圖實現Iterator接口。之前的代碼是構建鏈接位置列表的方式,我認爲並不重要...

public class LinkedPositionalList<E> implements PositionalList<E> { 
    private static class Node<E> implements Position<E> { 
     private E element; 
     private Node<E> prev; 
     private Node<E> next; 

     public Node(E e, Node<E> p, Node<E> n) { 
      element=e; 
      prev=p; 
      next=n; 
     } 
     public E getElement() throws IllegalStateException { 
      if (next == null) { 
       throw new IllegalStateException("Position no longer valid"); 
      } 
      return element; 
     } 

     public Node<E> getPrev() { 
      return prev; 
     } 

     public Node<E> getNext() { 
      return next; 
     } 

     public void setElement(E e) { 
      element=e; 
     } 

     public void setPrev(Node<E> prev) { 
      this.prev = prev; 
     } 

     public void setNext(Node<E> next) { 
      this.next=next; 
     } 
    } 
    private Node<E> header; 
    private Node<E> trailer; 
    private int size=0; 

    public LinkedPositionalList() { 
     header = new Node<>(null, null, null); 
     trailer = new Node<>(null, header, null); 
     header.setNext(trailer); 
    } 
    private Node<E> validate(Position p)throws IllegalArgumentException { 
     if (!(p instanceof Node)) { 
      throw new IllegalArgumentException("Invalid p"); 
     } 
     Node<E> node=(Node<E>)p; 
     if (node.getNext() == null) { 
      throw new IllegalArgumentException("p is no longer in the list"); 
     } 
     return node; 
    } 

    private Position<E> position(Node<E> node) { 
     if (node == header || node == trailer) { 
      return null; 
     } 
     return node; 
    } 

    public int size() { 
     return size; 
    } 

    public boolean isEmpty() { 
     return size == 0; 
    } 

    public Position<E> first() { 
     return position(header.getNext()); 
    } 

    public Position<E> last() { 
     return position(trailer.getPrev()); 
    } 

    public Position<E> before(Position<E> p) throws IllegalArgumentException { 
     Node<E> node = validate(p); 
     return position(node.getPrev()); 
    } 
    public Position<E> after(Position<E> p) throws IllegalArgumentException { 
     Node<E> node = validate(p); 
     return position(node.getNext()); 
    } 

    public Position<E> addBetween(E e, Node<E> pred, Node<E> succ) { 
     Node<E> newest = new Node<>(e, pred, succ); 
     pred.setNext(newest); 
     succ.setPrev(newest); 
     size++;return newest; 
    } 

    public Position<E> addFirst(E e) { 
     return addBetween(e, header, header.getNext()); 
    } 

    public Position<E> addLast(E e) { 
     return addBetween(e, trailer.getPrev(), trailer); 

    } 

    public Position<E> addBefore(Position<E> p, E e) throws IllegalArgumentException { 
     Node<E> node = validate(p); 
     return addBetween(e, node.getPrev(), node); 
    } 
    public Position<E> addAfter(Position<E> p,E e) throws IllegalArgumentException { 
     Node<E> node = validate(p); 
     return addBetween(e,node,node.getNext()); 
    } 

    public E set(Position<E> p, E e) throws IllegalArgumentException { 
     Node<E> node = validate(p); 
     E answer = node.getElement(); 
     node.setElement(e); 
     return answer; 
    } 
    public E remove(Position<E> p)throws IllegalArgumentException { 
     Node<E> node = validate(p); 
     Node<E> pre = node.getPrev(); 
     Node<E> succ = node.getNext(); 
     pre.setNext(succ); 
     succ.setPrev(pre); 
     size--; 
     E answer = node.getElement(); 
     node.setNext(null); 
     node.setPrev(null); 
     node.setElement(null); 
     return answer; 
    } 

//Here is the part that I think should be redesigned!!!! 

private class PositionIterator implements Iterator<Position<E>> { 
    private Position<E> cursor = first(); // position of the next element to report 
    private Position<E> recent = null; // position of last reported element 

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

    public Position<E> next() throws NoSuchElementException { 
     if (cursor == null) throw new NoSuchElementException("nothing left"); 
     recent = cursor; // element at this position might later be removed 
     cursor = after(cursor); 
     return recent; 
    } 

    public void remove() throws IllegalStateException { 
     if (recent == null) throw new IllegalStateException("nothing to remove"); 
     LinkedPositionalList.this.remove(recent); // remove from outer list 
     recent = null; // do not allow remove again until next is called 
    } 

} //------------ end of nested PositionIterator class ------------ 

    //---------------- nested PositionIterable class ---------------- 
    private class PositionIterable implements Iterable<Position<E>> { 
     public Iterator<Position<E>> iterator() { return new PositionIterator(); } 
    } //------------ end of nested PositionIterable class ------------ 


    public Iterable<Position<E>> positions() { 
     return new PositionIterable(); // create a new instance of the inner class 
    } 

    //---------------- nested ElementIterator class ---------------- 

    private class ElementIterator implements Iterator<E> { 
     Iterator<Position<E>> posIterator = new PositionIterator(); 
     public boolean hasNext() { return posIterator.hasNext(); } 
     public E next() { return posIterator.next().getElement(); } // return element! 
     public void remove() { posIterator.remove(); } 
    } 


    public Iterator<E> iterator() { return new ElementIterator(); } 



} 
+0

起初,我上傳了一個完全錯誤的版本...我需要修改並添加圖片來描述情況 –

回答

2

對於內置的Java集合框架類,如果你只是想要的物品,使用方法:

for (String item : list) { 
    // do something with item 
} 

使用顯式迭代器(這樣你就可以,實例,請使用迭代器的remove()法),你可以使用一個普通for循環:

for (Iterator<String> iter = list.iterator(); iter.hasNext();) { 
    String item = iter.next(); 
    // do something with item 
} 

當然,你也可以使用一個while循環。

對於您的特定班級,很難判斷上述內容是否適用,因爲您尚未發佈PositionalList的定義。

for (String str : list) { 
} 

這是Java for-each循環的正確語法:

+0

第二個工程,但是fisrt ont失敗。 –

+0

我按照你的建議先做。問題中的for_each循環顯然是錯誤的.IDE使它成爲第二種方式,我嘗試刪除它,但忘記像以前一樣更改它..... –

+0

@HqLi - 我的猜測是您的列表類沒有實現'Iterable ',但確實有一個迭代器()'簽名'Iterator '的方法。如果'PositionalList'沒有實現某種類型的'Iterable',則可以修改LinkedPositionalList的聲明以包含'implements Iterable ',然後'for-each'循環應該工作。 –

0

替換爲內循環。