JDK-6687277 : hasNext() needs to be made more robust
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util
  • Affected Version: 6u6
  • Priority: P2
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2008-04-11
  • Updated: 2016-05-24
  • Resolved: 2008-11-18
Related Reports
Duplicate :  
Duplicate :  
Description
There is a bug in AbstractList in private class Itr

method : hasNext()

public boolean hasNext() {
            return cursor != size();
	}

------------------
It should be:
return cursor < size();

Below is some sample code that exercises the problem.

I create a List with 2 elements and remove the second element.
When I step into hasNext() in a debugger
cursor == 2 and size == 1

Thus hasNext() should return false.  It obviously is supposed to return true if the cursor is less than the size.  It returns true -- even though it does not "has Next".

Granted -- the code is terrible.  It removes an item from the list instead of removing it from the iterator.  But it was nevertheless introduced into production code.
Just changing "!=" to "<" will make AbstractList more robust.

package quickie;
import java.util.*;
/**
 *
 * @author bnevins
 */
public class Main
{
    Main() {
        
    }
    public static void main(String[] args)
    {
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("b");
        
        Iterator iter = list.iterator();
        while(iter.hasNext())
        {
            String s = (String)iter.next();
            if(s.equals("b"))
                list.remove(s);
        }
    }    
   }

Comments
EVALUATION API doc in Iterator.remove() says "... The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method. "
18-11-2008