2017-06-18 68 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

替换为内循环。