Package javolution.util

Source Code of javolution.util.FastList$FastListIterator

/*
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
* Copyright (C) 2005 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javolution.util;

import java.io.IOException;

import java.util.NoSuchElementException;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.IllegalStateException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import javax.realtime.MemoryArea;
import javolution.context.ObjectFactory;
import javolution.context.PersistentContext;
import javolution.lang.Reusable;

/**
* <p> This class represents a linked list with real-time behavior;
*     smooth capacity increase and no memory allocation as long as the
*     list size does not exceed its initial capacity.</p>
*
* <p> All of the operations perform as could be expected for a doubly-linked
*     list ({@link #addLast insertion}/{@link #removeLast() deletion}
*     at the end of the list are nonetheless the fastest).
*     Operations that index into the list will traverse the list from
*     the begining or the end whichever is closer to the specified index.
*     Random access operations can be significantly accelerated by
*     {@link #subList splitting} the list into smaller ones.</p>
*
* <p> {@link FastList} (as for any {@link FastCollection} sub-class) supports
*     fast iterations without using iterators.[code]
*     FastList<String> list = new FastList<String>();
*     for (FastList.Node<String> n = list.head(), end = list.tail(); (n = n.getNext()) != end;) {
*         String value = n.getValue(); // No typecast necessary.   
*     }[/code]</p>
*    
* <p> {@link FastList} are {@link Reusable reusable}, they maintain
*     internal pools of {@link Node nodes} objects. When a node is removed
*     from its list, it is automatically restored to its pool.</p>
*
* <p> Custom list implementations may override the {@link #newNode} method
*     in order to return their own {@link Node} implementation (with
*     additional fields for example).</p>
*    
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, December 18, 2006
*/
public class FastList <E> extends FastCollection <E>
implements List <E> , Reusable {

    /**
     * Holds the main list factory.
     */
    private static final ObjectFactory FACTORY = new ObjectFactory() {

        public Object create() {
            return new FastList();
        }
       
    };

    /**
     * Holds the node marking the beginning of the list (not included).
     */
    private transient Node <E> _head = newNode();

    /**
     * Holds the node marking the end of the list (not included).
     */
    private transient Node <E> _tail = newNode();

    /**
     * Holds the value comparator.
     */
    private transient FastComparator <? super E> _valueComparator = FastComparator.DEFAULT;

    /**
     * Holds the current size.
     */
    private transient int _size;

    /**
     * Creates a list of small initial capacity.
     */
    public FastList() {
        this(4);
    }

    /**
     * Creates a persistent list associated to the specified unique identifier
     * (convenience method).
     *
     * @param id the unique identifier for this map.
     * @throws IllegalArgumentException if the identifier is not unique.
     * @see javolution.context.PersistentContext.Reference
     */
    public FastList(String id) {
        this();
        new PersistentContext.Reference(id, this) {
            protected void notifyChange() {
                FastList.this.clear();
                FastList.this.addAll((FastList) this.get());
            }
        };
    }

    /**
     * Creates a list of specified initial capacity; unless the list size
     * reaches the specified capacity, operations on this list will not allocate
     * memory (no lazy object creation).
     *
     * @param capacity the initial capacity.
     */
    public FastList(int capacity) {
        _head._next = _tail;
        _tail._previous = _head;
        Node <E> previous = _tail;
        for (int i = 0; i++ < capacity;) {
            Node <E> newNode = newNode();
            newNode._previous = previous;
            previous._next = newNode;
            previous = newNode;
        }
    }

    /**
     * Creates a list containing the specified values, in the order they
     * are returned by the collection's iterator.
     *
     * @param values the values to be placed into this list.
     */
    public FastList(Collection <? extends E> values) {
        this(values.size());
        addAll(values);
    }

    /**
     * Returns a new, preallocated or {@link #recycle recycled} list instance
     * (on the stack when executing in a {@link javolution.context.StackContext
     * StackContext}).
     *
     * @return a new, preallocated or recycled list instance.
     */
    public static <E> FastList <E> newInstance() {
        return (FastList <E> ) FACTORY.object();
    }

    /**
     * Recycles a list {@link #newInstance() instance} immediately
     * (on the stack when executing in a {@link javolution.context.StackContext
     * StackContext}).
     */
    public static void recycle(FastList instance) {
        FACTORY.recycle(instance);
    }

    /**
     * Appends the specified value to the end of this list
     * (equivalent to {@link #addLast}).
     *
     * @param value the value to be appended to this list.
     * @return <code>true</code> (as per the general contract of the
     *         <code>Collection.add</code> method).
     */
    public final boolean add( E value) {
        addLast(value);
        return true;
    }
    /**
     * Returns the value at the specified position in this list.
     *
     * @param index the index of value to return.
     * @return the value at the specified position in this list.
     * @throws IndexOutOfBoundsException if <code>(index < 0) ||
     *         (index >= size())</code>
     */
    public final  E get(int index) {
        if ((index < 0) || (index >= _size))
            throw new IndexOutOfBoundsException("index: " + index);
        return nodeAt(index)._value;
    }

    /**
     * Replaces the value at the specified position in this list with the
     * specified value.
     *
     * @param index the index of value to replace.
     * @param value the value to be stored at the specified position.
     * @return the value previously at the specified position.
     * @throws IndexOutOfBoundsException if <code>(index < 0) ||
     *         (index >= size())</code>
     */
    public final  E set(int index,  E value) {
        if ((index < 0) || (index >= _size))
            throw new IndexOutOfBoundsException("index: " + index);
        final Node <E> node = nodeAt(index);
         E previousValue = node._value;
        node._value = value;
        return previousValue;
    }

    /**
     * Inserts the specified value at the specified position in this list.
     * Shifts the value currently at that position
     * (if any) and any subsequent values to the right (adds one to their
     * indices).
     *
     * @param index the index at which the specified value is to be inserted.
     * @param value the value to be inserted.
     * @throws IndexOutOfBoundsException if <code>(index < 0) ||
     *         (index > size())</code>
     */
    public final void add(int index,  E value) {
        if ((index < 0) || (index > _size))
            throw new IndexOutOfBoundsException("index: " + index);
        addBefore(nodeAt(index), value);
    }

    /**
     * Inserts all of the values in the specified collection into this
     * list at the specified position. Shifts the value currently at that
     * position (if any) and any subsequent values to the right
     * (increases their indices).
     *
     * @param index the index at which to insert first value from the specified
     *        collection.
     * @param values the values to be inserted into this list.
     * @return <code>true</code> if this list changed as a result of the call;
     *         <code>false</code> otherwise.
     * @throws IndexOutOfBoundsException if <code>(index < 0) ||
     *         (index > size())</code>
     */
    public final boolean addAll(int index, Collection <? extends E> values) {
        if ((index < 0) || (index > _size))
            throw new IndexOutOfBoundsException("index: " + index);
        final Node indexNode = nodeAt(index);
        Iterator <? extends E> i = values.iterator();
        while (i.hasNext()) {
            addBefore(indexNode, i.next());
        }
        return values.size() != 0;
    }

    /**
     * Removes the value at the specified position in this list.
     * Shifts any subsequent values to the left (subtracts one
     * from their indices). Returns the value that was removed from the
     * list.
     *
     * @param index the index of the value to removed.
     * @return the value previously at the specified position.
     * @throws IndexOutOfBoundsException if <code>(index < 0) ||
     *         (index >= size())</code>
     */
    public final  E remove(int index) {
        if ((index < 0) || (index >= _size))
            throw new IndexOutOfBoundsException("index: " + index);
        final Node <E> node = nodeAt(index);
         E previousValue = node._value;
        delete(node);
        return previousValue;
    }

    /**
     * Returns the index in this list of the first occurrence of the specified
     * value, or -1 if this list does not contain this value.
     *
     * @param value the value to search for.
     * @return the index in this list of the first occurrence of the specified
     *         value, or -1 if this list does not contain this value.
     */
    public final int indexOf(Object value) {
        final FastComparator comp = this.getValueComparator();
        int index = 0;
        for (Node n = _head, end = _tail; (n = n._next) != end; index++) {
            if (comp == FastComparator.DEFAULT ? defaultEquals(value, n._value)
                    : comp.areEqual(value, n._value))
                return index;
        }
        return -1;
    }

    /**
     * Returns the index in this list of the last occurrence of the specified
     * value, or -1 if this list does not contain this value.
     *
     * @param value the value to search for.
     * @return the index in this list of the last occurrence of the specified
     *         value, or -1 if this list does not contain this value.
     */
    public final int lastIndexOf(Object value) {
        final FastComparator comp = this.getValueComparator();
        int index = size() - 1;
        for (Node n = _tail, end = _head; (n = n._previous) != end; index--) {
            if (comp == FastComparator.DEFAULT ? defaultEquals(value, n._value)
                    : comp.areEqual(value, n._value))
                return index;
        }
        return -1;
    }

    /**
     * Returns a simple iterator over the elements in this list
     * (allocated on the stack when executed in a
     * {@link javolution.context.StackContext StackContext}).
     *
     * @return an iterator over this list values.
     */
    public Iterator <E> iterator() {
        return listIterator();
    }

    /**
     * Returns a list iterator over the elements in this list
     * (allocated on the stack when executed in a
     * {@link javolution.context.StackContext StackContext}).
     *
     * @return an iterator over this list values.
     */
    public ListIterator <E> listIterator() {
        return FastListIterator.valueOf(this, _head._next, 0, _size);
    }

    /**
     * Returns a list iterator from the specified position
     * (allocated on the stack when executed in a
     * {@link javolution.context.StackContext StackContext}).
     *
     * The specified index indicates the first value that would be returned by
     * an initial call to the <code>next</code> method.  An initial call to
     * the <code>previous</code> method would return the value with the
     * specified index minus one.
     *
     * @param index index of first value to be returned from the
     *        list iterator (by a call to the <code>next</code> method).
     * @return a list iterator over the values in this list
     *         starting at the specified position in this list.
     * @throws IndexOutOfBoundsException if the index is out of range
     *        [code](index < 0 || index > size())[/code].
     */
    public ListIterator <E> listIterator(int index) {
        if ((index < 0) || (index > _size))
            throw new IndexOutOfBoundsException("index: " + index);
        return FastListIterator.valueOf(this, nodeAt(index), index, _size);
    }

    /**
     * Returns a view of the portion of this list between the specified
     * indexes (allocated from the "stack" when executing in a
     * {@link javolution.context.StackContext StackContext}).
     * If the specified indexes are equal, the returned list is empty.
     * The returned list is backed by this list, so non-structural changes in
     * the returned list are reflected in this list, and vice-versa.
     *
     * This method eliminates the need for explicit range operations (of
     * the sort that commonly exist for arrays). Any operation that expects
     * a list can be used as a range operation by passing a subList view
     * instead of a whole list.  For example, the following idiom
     * removes a range of values from a list:
     * <code>list.subList(from, to).clear();</code>
     * Similar idioms may be constructed for <code>indexOf</code> and
     * <code>lastIndexOf</code>, and all of the algorithms in the
     * <code>Collections</code> class can be applied to a subList.
     *
     * The semantics of the list returned by this method become undefined if
     * the backing list (i.e., this list) is <i>structurally modified</i> in
     * any way other than via the returned list (structural modifications are
     * those that change the size of this list, or otherwise perturb it in such
     * a fashion that iterations in progress may yield incorrect results).
     *
     * @param fromIndex low endpoint (inclusive) of the subList.
     * @param toIndex high endpoint (exclusive) of the subList.
     * @return a view of the specified range within this list.
     *
     * @throws IndexOutOfBoundsException if [code](fromIndex < 0 ||
     *          toIndex > size || fromIndex < toIndex)[/code]
     */
    public final List <E> subList(int fromIndex, int toIndex) {
        if ((fromIndex < 0) || (toIndex > _size) || (fromIndex > toIndex))
            throw new IndexOutOfBoundsException("fromIndex: " + fromIndex
                    + ", toIndex: " + toIndex + " for list of size: " + _size);
        return SubList.valueOf(this, nodeAt(fromIndex)._previous,
                nodeAt(toIndex), toIndex - fromIndex);
    }

    /**
     * Returns the first value of this list.
     *
     * @return this list's first value.
     * @throws NoSuchElementException if this list is empty.
     */
    public final  E getFirst() {
        final Node <E> node = _head._next;
        if (node == _tail)
            throw new NoSuchElementException();
        return node._value;
    }

    /**
     * Returns the last value of this list.
     *
     * @return this list's last value.
     * @throws NoSuchElementException if this list is empty.
     */
    public final  E getLast() {
        final Node <E> node = _tail._previous;
        if (node == _head)
            throw new NoSuchElementException();
        return node._value;
    }

    /**
     * Inserts the specified value at the beginning of this list.
     *
     * @param value the value to be inserted.
     */
    public final void addFirst( E value) {
        addBefore(_head._next, value);
    }

    /**
     * Appends the specified value to the end of this list <i>(fast)</i>.
     *
     * @param value the value to be inserted.
     */
    public void addLast( E value) { // Optimized.
        if (_tail._next == null) {
            increaseCapacity();
        }
        _tail._value = value;
        _tail = _tail._next;
        _size++;
    }

    /**
     * Removes and returns the first value of this list.
     *
     * @return this list's first value before this call.
     * @throws NoSuchElementException if this list is empty.
     */
    public final  E removeFirst() {
        final Node <E> first = _head._next;
        if (first == _tail)
            throw new NoSuchElementException();
         E previousValue = first._value;
        delete(first);
        return previousValue;
    }

    /**
     * Removes and returns the last value of this list <i>(fast)</i>.
     *
     * @return this list's last value before this call.
     * @throws NoSuchElementException if this list is empty.
     */
    public final  E removeLast() {
        if (_size == 0)
            throw new NoSuchElementException();
        _size--;
        final Node <E> last = _tail._previous;
        final  E previousValue = last._value;
        _tail = last;
        last._value = null;
        return previousValue;
    }

    ///////////////////////
    // Nodes operations. //
    ///////////////////////

    /**
     * Inserts the specified value before the specified Node.
     *
     * @param next the Node before which this value is inserted.
     * @param value the value to be inserted.  
     */
    public final void addBefore(Node <E> next,  E value) {
        if (_tail._next == null) {
            increaseCapacity();// Increases capacity.
        }
        final Node newNode = _tail._next;
        // Detaches newNode.
        final Node tailNext = _tail._next = newNode._next;
        if (tailNext != null) {
            tailNext._previous = _tail;
        }
        // Inserts before next.
        final Node previous = next._previous;
        previous._next = newNode;
        next._previous = newNode;
        newNode._next = next;
        newNode._previous = previous;

        newNode._value = value;
        _size++;
    }

    /**
     * Returns the node at the specified index. This method returns
     * the {@link #headNode} node when [code]index < 0 [/code] or
     * the {@link #tailNode} node when [code]index >= size()[/code].
     *
     * @param index the index of the Node to return.
     */
    private final Node <E> nodeAt(int index) {
        // We cannot do backward search because of thread-safety.
        Node <E> node = _head;
        for (int i = index; i-- >= 0;) {
            node = node._next;
        }
        return node;
    }

    // Implements FastCollection abstract method.
    public final Node<E>head() {
        return _head;
    }

    // Implements FastCollection abstract method.
    public final Node<E>tail() {
        return _tail;
    }

    // Implements FastCollection abstract method.
    public final  E valueOf(Record record) {
        return ((Node <E> ) record)._value;
    }

    // Implements FastCollection abstract method.
    public final void delete(Record record) {
        Node <E> node = (Node <E> ) record;
        _size--;
        node._value = null;
        // Detaches.
        node._previous._next = node._next;
        node._next._previous = node._previous;
        // Inserts after _tail.
        final Node <E> next = _tail._next;
        node._previous = _tail;
        node._next = next;
        _tail._next = node;
        if (next != null) {
            next._previous = node;
        }
    }

    // Overrides (optimization).
    public final boolean contains(Object value) {
        return indexOf(value) >= 0;
    }

    ///////////////////////
    // Contract Methods. //
    ///////////////////////

    // Implements abstract method.
    public final int size() {
        return _size;
    }

    // Overrides (optimization).
    public final void clear() {
        _size = 0;
        for (Node <E> n = _head, end = _tail; (n = n._next) != end;) {
            n._value = null;
        }
        _tail = _head._next;
    }

    /**
     * Sets the comparator to use for value equality.
     *
     * @param comparator the value comparator.
     * @return <code>this</code>
     */
    public FastList <E> setValueComparator(
            FastComparator <? super E> comparator) {
        _valueComparator = comparator;
        return this;
    }

    // Overrides.
    public FastComparator <? super E> getValueComparator() {
        return _valueComparator;
    }

    // Overrides  to return a list (JDK1.5+).
    public  List<E> unmodifiable() {
        return ( List<E> ) super.unmodifiable();
    }

    /**
     * Returns a new node for this list; this method can be overriden by
     * custom list implementation.
     *
     * @return a new node.
     */
    protected Node <E> newNode() {
        return new Node();
    }

    // Requires special handling during de-serialization process.
    private void readObject(ObjectInputStream stream) throws IOException,
            ClassNotFoundException {

        // Initial setup.
        _head = new Node();
        _tail = new Node();
        _head._next = _tail;
        _tail._previous = _head;

        setValueComparator((FastComparator) stream.readObject());
        final int size = stream.readInt();
        for (int i = size; i-- != 0;) {
            addLast(( E ) stream.readObject());
        }
    }

    // Requires special handling during serialization process.
    private void writeObject(ObjectOutputStream stream) throws IOException {
        stream.writeObject(getValueComparator());
        stream.writeInt(_size);
        Node node = _head;
        for (int i = _size; i-- != 0;) {
            node = node._next;
            stream.writeObject(node._value);
        }
    }

    // Increases capacity (_tail._next == null)
    private void increaseCapacity() {
        MemoryArea.getMemoryArea(this).executeInArea(new Runnable() {
            public void run() {
                Node <E> newNode0 = newNode();
                _tail._next = newNode0;
                newNode0._previous = _tail;

                Node <E> newNode1 = newNode();
                newNode0._next = newNode1;
                newNode1._previous = newNode0;

                Node <E> newNode2 = newNode();
                newNode1._next = newNode2;
                newNode2._previous = newNode1;

                Node <E> newNode3 = newNode();
                newNode2._next = newNode3;
                newNode3._previous = newNode2;
            }
        });
    }


    // Implements Reusable interface.
    public void reset() {
        clear();
        this.setValueComparator(FastComparator.DEFAULT);
    }

    /**
     * This class represents a {@link FastList} node; it allows for direct
     * iteration over the list {@link #getValue values}.
     * Custom {@link FastList} may use a derived implementation.
     * For example:[code]
     *    static class MyList<E,X> extends FastList<E> {
     *        protected MyNode newNode() {
     *            return new MyNode();
     *        }
     *        class MyNode extends Node<E> {
     *            X xxx; // Additional node field (e.g. cross references).
     *        }       
     *    }[/code]
     */
    public static class Node <E> implements Record, Serializable {

        /**
         * Holds the next node.
         */
        private Node <E> _next;

        /**
         * Holds the previous node.
         */
        private Node <E> _previous;

        /**
         * Holds the node value.
         */
        private  E _value;

        /**
         * Default constructor.
         */
        protected Node() {
        }

        /**
         * Returns the value for this node.
         *
         * @return the node value.
         */
        public final  E getValue() {
            return _value;
        }

        // Implements Record interface.
        public final Node<E>getNext() {
            return _next;
        }

        // Implements Record interface.
        public final Node<E>getPrevious() {
            return _previous;
        }

    }

    /**
     * This inner class implements a sub-list.
     */
    private static final class SubList extends FastCollection implements List,
            Serializable {

        private static final ObjectFactory FACTORY = new ObjectFactory() {
            protected Object create() {
                return new SubList();
            }

            protected void cleanup(Object obj) {
                SubList sl = (SubList) obj;
                sl._list = null;
                sl._head = null;
                sl._tail = null;
            }
        };

        private FastList _list;

        private Node _head;

        private Node _tail;

        private int _size;

        public static SubList valueOf(FastList list, Node head, Node tail,
                int size) {
            SubList subList = (SubList) FACTORY.object();
            subList._list = list;
            subList._head = head;
            subList._tail = tail;
            subList._size = size;
            return subList;
        }

        public int size() {
            return _size;
        }

        public Record head() {
            return _head;
        }

        public Record tail() {
            return _tail;
        }

        public Object valueOf(Record record) {
            return _list.valueOf(record);
        }

        public void delete(Record record) {
            _list.delete(record);
        }

        public boolean addAll(int index, Collection values) {
            if ((index < 0) || (index > _size))
                throw new IndexOutOfBoundsException("index: " + index);
            final Node indexNode = nodeAt(index);
            Iterator i = values.iterator();
            while (i.hasNext()) {
                _list.addBefore(indexNode, i.next());
            }
            return values.size() != 0;
        }

        public Object get(int index) {
            if ((index < 0) || (index >= _size))
                throw new IndexOutOfBoundsException("index: " + index);
            return nodeAt(index)._value;
        }

        public Object set(int index, Object value) {
            if ((index < 0) || (index >= _size))
                throw new IndexOutOfBoundsException("index: " + index);
            final Node node = nodeAt(index);
            Object previousValue = node._value;
            node._value = value;
            return previousValue;
        }

        public void add(int index, Object element) {
            if ((index < 0) || (index > _size))
                throw new IndexOutOfBoundsException("index: " + index);
            _list.addBefore(nodeAt(index), element);
        }

        public Object remove(int index) {
            if ((index < 0) || (index >= _size))
                throw new IndexOutOfBoundsException("index: " + index);
            final Node node = nodeAt(index);
            Object previousValue = node._value;
            _list.delete(node);
            return previousValue;
        }

        public int indexOf(Object value) {
            final FastComparator comp = _list.getValueComparator();
            int index = 0;
            for (Node n = _head, end = _tail; (n = n._next) != end; index++) {
                if (comp.areEqual(value, n._value))
                    return index;
            }
            return -1;
        }

        public int lastIndexOf(Object value) {
            final FastComparator comp = this.getValueComparator();
            int index = size() - 1;
            for (Node n = _tail, end = _head; (n = n._previous) != end; index--) {
                if (comp.areEqual(value, n._value)) {
                    return index;
                }
            }
            return -1;
        }

        public ListIterator listIterator() {
            return listIterator(0);
        }

        public ListIterator listIterator(int index) {
            if ((index >= 0) && (index <= _size)) {
                return FastListIterator.valueOf(_list, nodeAt(index), index,
                        _size);
            } else {
                throw new IndexOutOfBoundsException("index: " + index
                        + " for list of size: " + _size);
            }
        }

        public List subList(int fromIndex, int toIndex) {
            if ((fromIndex < 0) || (toIndex > _size) || (fromIndex > toIndex))
                throw new IndexOutOfBoundsException("fromIndex: " + fromIndex
                        + ", toIndex: " + toIndex + " for list of size: "
                        + _size);
            SubList subList = SubList.valueOf(_list,
                    nodeAt(fromIndex)._previous, nodeAt(toIndex), toIndex
                            - fromIndex);
            return subList;
        }

        private final Node nodeAt(int index) {
            if (index <= (_size >> 1)) { // Forward search.
                Node node = _head;
                for (int i = index; i-- >= 0;) {
                    node = node._next;
                }
                return node;
            } else { // Backward search.
                Node node = _tail;
                for (int i = _size - index; i-- > 0;) {
                    node = node._previous;
                }
                return node;
            }
        }
    }

    /**
     * This inner class implements a fast list iterator.
     */
    private static final class FastListIterator implements ListIterator {

        private static final ObjectFactory FACTORY = new ObjectFactory() {
            protected Object create() {
                return new FastListIterator();
            }

            protected void cleanup(Object obj) {
                FastListIterator i = (FastListIterator) obj;
                i._list = null;
                i._currentNode = null;
                i._nextNode = null;
            }
        };

        private FastList _list;

        private Node _nextNode;

        private Node _currentNode;

        private int _length;

        private int _nextIndex;

        public static FastListIterator valueOf(FastList list, Node nextNode,
                int nextIndex, int size) {
            FastListIterator itr = (FastListIterator) FACTORY.object();
            itr._list = list;
            itr._nextNode = nextNode;
            itr._nextIndex = nextIndex;
            itr._length = size;
            return itr;
        }

        public boolean hasNext() {
            return (_nextIndex != _length);
        }

        public Object next() {
            if (_nextIndex == _length)
                throw new NoSuchElementException();
            _nextIndex++;
            _currentNode = _nextNode;
            _nextNode = _nextNode._next;
            return _currentNode._value;
        }

        public int nextIndex() {
            return _nextIndex;
        }

        public boolean hasPrevious() {
            return _nextIndex != 0;
        }

        public Object previous() {
            if (_nextIndex == 0)
                throw new NoSuchElementException();
            _nextIndex--;
            _currentNode = _nextNode = _nextNode._previous;
            return _currentNode._value;
        }

        public int previousIndex() {
            return _nextIndex - 1;
        }

        public void add(Object o) {
            _list.addBefore(_nextNode, o);
            _currentNode = null;
            _length++;
            _nextIndex++;
        }

        public void set(Object o) {
            if (_currentNode == null)
                throw new IllegalStateException();
            _currentNode._value = o;
        }

        public void remove() {
            if (_currentNode == null)
                throw new IllegalStateException();
            if (_nextNode == _currentNode) { // previous() has been called.
                _nextNode = _nextNode._next;
            } else {
                _nextIndex--;
            }
            _list.delete(_currentNode);
            _currentNode = null;
            _length--;
        }
    }

    // For inlining of default comparator.
    private static boolean defaultEquals(Object o1, Object o2) {
        return (o1 == null) ? (o2 == null) : (o1 == o2) || o1.equals(o2);
    }

    private static final long serialVersionUID = 1L;

}
TOP

Related Classes of javolution.util.FastList$FastListIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.