Using ListIterator to move back and forth over a LinkedList in Java

前端 未结 3 651
甜味超标
甜味超标 2021-02-18 17:26

I have a LinkedList over which I need to iterate back and forth multiple times. I am using it to keep track of a series of pages in a workflow that will be created dynamically.

相关标签:
3条回答
  • 2021-02-18 17:45

    This should do your job:

    public class Main {
        public static void main(String[] args) {
            final LinkedList<String> list = new LinkedList<String> ();
    
            list.add ("1"); list.add ("2"); list.add ("3"); list.add ("4");
    
            final MyIterator<String> it = new MyIterator (list.listIterator());
    
            System.out.println(it.next());
            System.out.println(it.next ());
            System.out.println(it.next ());
            System.out.println(it.previous ());
            System.out.println(it.previous ());
            System.out.println(it.next ());
        }
    
        public static class MyIterator<T> {
    
            private final ListIterator<T> listIterator;
    
            private boolean nextWasCalled = false;
            private boolean previousWasCalled = false;
    
            public MyIterator(ListIterator<T> listIterator) {
                this.listIterator = listIterator;
            }
    
            public T next() {
                nextWasCalled = true;
                if (previousWasCalled) {
                    previousWasCalled = false;
                    listIterator.next ();
                }
                return listIterator.next ();
            }
    
            public T previous() {
                if (nextWasCalled) {
                    listIterator.previous();
                    nextWasCalled = false;
                }
                previousWasCalled = true;
                return listIterator.previous();
            }
    
        }   
    }
    

    And a fiddle for it.

    0 讨论(0)
  • 2021-02-18 17:51

    Do something like this (pseudocode) --

    class SkipIterator extends ListIterator {
    
        public E previous(){
            E n = super.previous();
            return super.previous();
        }
    
        ...
    
    }
    

    then:

    LinkedList<String> navigationCases;
    navigationCases.add("page1");
    navigationCases.add("page2");
    navigationCases.add("page3");
    navigationCases.add("page4");
    
    SkipIterator navigationItr = (SkipIterator)navigationCases.listIterator();
    navigationItr.next(); // Returns page1
    navigationItr.next(); // Returns page2
    navigationItr.previous(); // Returns page1
    

    Cheers

    0 讨论(0)
  • 2021-02-18 17:56

    ListIterator was designed to behave this way. See the conversation beneath ShyJ's answer for the rationale.

    I find this behavior to be beyond idiotic, and have instead written a very simple alternative. Here's the Kotlin code with a extension function for ArrayLists:

    class ListIterator<E>(var list: ArrayList<E>) : Iterator<E> {
    
        private var cursor: Int = 0
    
        fun replace(newList: ArrayList<E>) {
            list = newList
            cursor = 0
        }
    
        override fun hasNext(): Boolean {
            return cursor + 1 < list.size
        }
    
        override fun next(): E {
            cursor++
            return current()
        }
    
        fun hasPrevious(): Boolean {
            return 0 <= cursor - 1
        }
    
        fun previous(): E {
            cursor--
            return current()
        }
    
        fun current(): E {
            return list[cursor]
        }
    
    }
    
    fun <E> ArrayList<E>.listFlippingIterator() = ListIterator(this)
    

    If you wish to include removal functionality, I highly recommend writing the API to explicitly instruct the iterator if it should remove left or right, e.g. by defining those methods as removeNext() and removePrevious().

    0 讨论(0)
提交回复
热议问题