java iterator无法应用于for_each

时间:2017-06-18 02:08:06

标签: java interface iterator

在Java 6th Edition中学习数据结构和算法时,我尝试自己构建一个链接位置列表。 Position实现Node来存储数据。 我想构建两个迭代器,一个用于迭代Position,另一个用于迭代Position中的元素。所以我认为两种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 ) {
    }

事实证明,第二个for-each不适用于类型,但第一个效果很好。那么如何让第二个for-each迭代器工作呢?

这是构建此类的代码: p.s.:代码很长。嵌套类的最后一部分试图实现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(); }



}

2 个答案:

答案 0 :(得分:2)

对于内置的Java Collection Framework类,如果只需要项目,请使用:

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

要使用显式迭代器(例如,您可以使用迭代器&#39; remove()方法),您可以使用常规for循环:

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

当然,您也可以使用while循环。

对于您的特定课程,由于您尚未发布PositionalList的定义,因此很难判断上述情况是否适用。

答案 1 :(得分:0)

用以下内容替换内循环:

for (String str : list) {
}

这是Java for-each循环的正确语法。