Iterator for a list of objects Given a list of objects, return an iterator for such a list. Looking for code-review, optimizations and best practices. Verifying complexity to be O(n) where n is sum of all objects, including elements of collections if contained. previously solved here.

public class FlattenIterator implements Iterator&lt;Object&gt; {

    private final Stack&lt;Iterator&lt;?&gt;&gt; iteratorStack;
    private Object next;

    public FlattenIterator(Iterable&lt;?&gt; list) {
        if (list == null) {
            throw new NullPointerException();
        }

        iteratorStack = new Stack&lt;Iterator&lt;?&gt;&gt;();
        iteratorStack.push(list.iterator());
    }


    private void moveToNext() {
       while ((next == null) &amp;&amp; !iteratorStack.empty()) {
            Iterator&lt;?&gt; itr = iteratorStack.peek();

            // if iterator is empty, then pop it from stack.
            if (!itr.hasNext()) {
                iteratorStack.pop();
            } else {
                final Object next = itr.next();
                if (next instanceof Iterable) {
                    iteratorStack.push(((Iterable&lt;?&gt;) next).iterator());
                    moveToNext();
                } else {
                    this.next = next;
                }
            }
        }
    }

    /**
     * Returns if there are any objects left to iterate over. This method 
     * can change the internal state of the object when it is called, but repeated
     * calls to it will not have any additional side effects.
     */
    public boolean hasNext() {
        moveToNext();
        return next != null;
    }

    /**
     * Returns the next element in our iteration, throwing a NoSuchElementException
     * if none is found. 
     */
    public Object next() {
        moveToNext();
        if (next == null) {
            throw new NoSuchElementException(); 
        }

        Object objectToReturn = next;
        next = null;
        return objectToReturn;
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }
}

public class FlattenIteratorTest {

    @Test
    public void testIterator() {
        /**
         *  &lt; &lt;1, 2&gt;, &lt;"abc", "xyz"&gt;  &lt;&lt;1, 2&gt;, &lt;"abc", "xyz"&gt;&gt; , a, 10 &gt;
         */
        List&lt;Object&gt; genericList = new ArrayList&lt;Object&gt;();

        // integer list
        List&lt;Integer&gt; listInteger = new ArrayList&lt;Integer&gt;(Arrays.asList(1, 2));

        // string list
        List&lt;String&gt; listString = new ArrayList&lt;String&gt;(Arrays.asList("abc", "xyz"));

        // nested lists.
        List&lt;Object&gt; nestedList = new ArrayList&lt;Object&gt;();
        nestedList.add(listInteger);
        nestedList.add(listString);

        genericList.add(listInteger);
        genericList.add(listString);
        genericList.add(nestedList);
        genericList.add('a');
        genericList.add(10);

        /**
         * A very simple test case.
         */
        FlattenIterator fi = new FlattenIterator(genericList); 
        final List&lt;Object&gt; listExpected = new ArrayList&lt;&gt;(Arrays.asList(1, 2, "abc", "xyz", 1, 2, "abc", "xyz", 'a', 10));
        final List&lt;Object&gt; listActual = new ArrayList&lt;&gt;();
        while (fi.hasNext()) {
           listActual.add(fi.next());
        }    
        assertTrue(listExpected.equals(listActual));
    }

    @Test
    public void testEmpty() {
        List&lt;Integer&gt; list = new ArrayList&lt;&gt;();
        list.addAll(list);
        FlattenIterator fi = new FlattenIterator(list);
        assertFalse(fi.hasNext());
    }

}
I'm going to hit the high notes on my phone and swing back later with details unless someone beats me to it. 

Allow null

Add a separate boolean field to track when next holds the actual next element rather than using null as a signal that it needs to be populated so that null elements can be supported.

Avoid Recursion

In this case, there's no reason for moveToNext to call itself. Continuing the loop should have the same effect. 

Use Generics

Even though you're stuck using Object for variables which may hold an element or an iterable, you can still add a generic type T to the class and specify it as the return type from next. At least, I think you can. :) 

Testing

When using the @Test annotation, you don't have to prefix each test method name with test. However, you really need more descriptive method names, and each test should validate one specific condition. 

Burn this into your brain: Arrange, Act, Assert. Arrange the test fixture in the initial state, perform the action being tested, and assert the results. It can become tedious to setup the fixture each time, but helper methods can ease the pain and promote DRYness.